2012-04-26 64 views
1

我有三個表:有什麼錯我的SQL查詢

CREATE TABLE `b10g_entries` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `permalink` text NOT NULL, 
    `title` varchar(300) NOT NULL, 
    `fullcontent` text NOT NULL, 
    `introcontent` text NOT NULL, 
    `dateadded` datetime NOT NULL, 
    `lastedited` datetime NOT NULL, 
    `author` varchar(40) NOT NULL, 
    `comments` int(11) NOT NULL DEFAULT '0', 
    `published` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=299 DEFAULT CHARSET=utf8 

CREATE TABLE `b10g_tag_map` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `tag_id` bigint(20) unsigned DEFAULT NULL, 
    `entry_id` bigint(20) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 

CREATE TABLE `b10g_tags` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `name` text NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 

而且我試圖讓前25個博客條目與他們的標籤(這就是爲什麼我使用許多一對多的關係)使用此查詢:

SELECT b10g_entries.*, GROUP_CONCAT(b10g_tags.name SEPARATOR ', ') 
AS tags FROM b10g_entries 
LEFT JOIN b10g_tag_map ON b10g_entries.id = b10g_tag_map.entry_id 
LEFT JOIN b10g_tags ON b10g_tag_map.tag_id = b10g_tags.id LIMIT 0, 25; 

但我只收到1條記錄。這個查詢有什麼問題? 謝謝。

+0

hmm。有趣的是 - 所以TEXT字段應該放在不同的表格中,因爲內容可以與其餘列相比得到相當大的比較 - 好點,我沒有想到這一點。我肯定會在BIGINT的參考表中添加索引,但是感謝您指出了這一點。 – Stann 2012-04-26 04:11:14

回答

1

添加GROUP BY子句。

現在,您將看到在該集合中找到的所有標籤的列表。相反,你只需要組中的人(通過輸入)。

SELECT b10g_entries.*, GROUP_CONCAT(b10g_tags.name SEPARATOR ', ') 
AS tags FROM b10g_entries 
LEFT JOIN b10g_tag_map ON b10g_entries.id = b10g_tag_map.entry_id 
LEFT JOIN b10g_tags ON b10g_tag_map.tag_id = b10g_tags.id 
GROUP BY b10g_entries.id 
+0

我想指出,這種方法可能不是很高效。在您的環境中進行測試,使其更像是輔助查詢來獲取標籤。 – zanlok 2012-04-26 03:35:09

+0

真棒。真棒到最大。謝謝zanlok。我的代碼中實際上有GROUP BY b10g_entries.id,但錯誤地將它放在LIMIT子句之後。 – Stann 2012-04-26 04:02:47

1

你有GROUP_CONCAT()聚合函數,但沒有使用過GROUP BY條款,所以你的結果將是一行。

請注意,在MySQL中,允許使用僅指定一列的GROUP BY,而多出現在SELECT列表中,但不能移植到其他RDBMS。相反,我第二次加入b10g_entries以連接該表中的所有其他列,而僅使用GROUP BY中的id

SELECT 
    b10g_entries_all.*, 
    GROUP_CONCAT(b10g_tags.name SEPARATOR ', ') AS tags 
FROM 
    /* Main table, used gor GROUP BY aggregate */ 
    b10g_entries 
    /* self join to pull in other columns without needing to put them in GROUP BY */ 
    JOIN b10g_entries b10g_entries_all ON b10g_entries.id = b10g_entries_all.id 
    LEFT JOIN b10g_tag_map ON b10g_entries.id = b10g_tag_map.entry_id 
    LEFT JOIN b10g_tags ON b10g_tag_map.tag_id = b10g_tags.id 
/* group on the entry id */ 
GROUP BY b10g_entries.id 
LIMIT 0, 25; 
+0

他比這個有更多的問題,imo。好點,但。 – zanlok 2012-04-26 03:35:59