2013-06-03 138 views
1

忍受我,這需要大量的前期信息來解釋我正在嘗試做什麼。我儘可能地將其儘可能通用化,以使事情更清晰。在一個查詢中,我希望能夠列出與另一個表中鏈接的標籤相匹配的頁面列表,並且這些標籤是分組的。我希望使用該項目的文本表示,而不是它的id,但是如果沒有別的,我可以做2個前置查詢來獲得tag_id和taggroup_id - 只是希望不必這樣做。通過鏈接表多條件連接

DB模式:

+-----------------------------------+ 
| taggroups       | 
+------------------+----------------+ 
| taggroup_id  | group_name  | 
+------------------+----------------+ 
| 1    | fruits   | 
+------------------+----------------+ 

+-----------------------------------------------+ 
| tags           | 
+-------------+-----------------+---------------+ 
| tag_id  | taggroup_id  | tag_name  | 
+-------------+-----------------+---------------+ 
| 1   | 1    | apple   | 
| 2   | 1    | orange  | 
| 3   | 1    | grape   | 
+-------------+-----------------+---------------+ 

+--------------------------------------+ 
| pages        | 
+------------------+-------------------+ 
| page_id   | title    | 
+------------------+-------------------+ 
| 99    | Doctor a day  | 
+------------------+-------------------+ 

+--------------------------------------------------+ 
| tags_to_pages         | 
+------------+----------+---------------+----------+ 
| join_id | tag_id | taggroup_id | page_id | 
+------------+----------+---------------+----------+ 
| 1   | 1  | 1    | 99  | 
| 2   | 2  | 1    | 99  | 
+------------+----------+---------------+----------+ 

測試查詢: 遠遠得到這個似乎並不能得到它的工作。

SELECT 
    pages.*, tags.tag_name, taggroups.group_name 
FROM 
    tags_to_pages 
    INNER JOIN taggroups as grp ON (
      grp.group_name = 'fruits' 
     AND 
      tags_to_pages.taggroup_id = grp.taggroup_id 
    ) 
    INNER JOIN tags as val ON (val.tag_name = 'apple' AND tags_to_pages.tag_id = val.tag_id) 
    LEFT JOIN pages ON (tags_to_pages.page_id = pages.page_id) 

此外,哪些表應該有索引,哪些索引應該被優化?

回答

0

我會做這種方式:

SELECT 
    pages.*, tags.tag_name, taggroups.group_name 
FROM 
    tags_to_pages 
    JOIN taggroups AS grp ON grp.taggroup_id = tags_to_pages.taggroup_id 
    JOIN tags AS val ON val.taggroup_id = grp.taggroup_id 
    JOIN pages ON tags_to_pages.page_id = pages.page_id 
WHERE 
    grp.group_name='fruits' 
    AND val.tag_name = 'apple' 

這不是你有什麼不同,但我把在JOIN條款連接標準和選擇標準的WHERE子句,這對我來說似乎更加整潔。

在重新輸入此查詢時,我發現您在某處我使用了tag_id,因此我改變了它,但我後悔我現在再也看不到它了。

我還擔心選擇標準 - 如果一個蘋果不會成爲一個水果?很明顯,在這種情況下,實際上是:-),但我認爲你應該只在查詢中指定水果名稱,而不是水果和組名,並讓數據庫自行排序。

另外,爲什麼要爲頁面使用標籤,tags_to_pages和taggroups以及OUTER JOIN的INNER JOIN?當然,如果沒有頁面,你最好不要返回行而不是一行,在NULLS上一半是完整的?

我只索引id列。

只是我的2p值得,真的。

編輯

我已成立的這個演示上www.sqlfiddle.com。當我更改SELECT列表中的別名時,您的original query工作正常。我attempt above並不可怕正常工作:-(。我曾與別名同樣的問題,一旦我固定他們的查詢返回相同的行兩次。

我又重新寫了從無到有的

SELECT pages.*, tags.tag_name, taggroups.group_name 
FROM pages 
JOIN tags_to_pages AS ttp ON ttp.page_id = pages.page_id 
JOIN tags ON tags.tag_id = ttp.tag_id 
JOIN taggroups ON taggroups.taggroup_id = ttp.taggroup_id 
WHERE taggroups.group_name = 'fruits' AND tags.tag_name='apple'; 

,它工作正常link

設置本演示中,它打動了我想知道爲什麼你在tags_to_pages表保存taggroup_id,我是「自學成才」,在SQL和數據庫(那意思就是:「當我走的時候我會補上,依靠做'有用'的事情,並相信直覺找到你什麼是'正確'「),但這不會打破正常化的想法嗎?tagstaggroups之間的連接不應該僅通過tags表中的taggroup_id列來定義?也許有人真的理解數據庫會出現,並把我的權利。

最後,我不知道爲什麼PHPMyAdmin只是掛起來,當你嘗試你的查詢。祝你好運!

+0

正如您從上述貨幣單位可以猜出的,我現在在英國,而且已經很晚了,所以現在我要睡覺了 - 我會在早上回復任何意見 - 即10小時。祝你好運。 – nurdglaw

+0

感謝nurd,你是否改變了查詢的結構或者它的邏輯。例如。它是以不同的方式做同樣的事情嗎?因爲我無法讓我的查詢擺在首位。 –

+0

爆炸 - 太慢,無法上牀!我更改爲在taggroupid上加入,而不是在某處添加tag_id: - |當查詢「不起作用」時,你遇到了什麼問題?它沒有返回,還是返回「錯誤的東西」? – nurdglaw