1

我有三张桌子:

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;

但我只拿回一张唱片。这个查询有什么问题?

4

2 回答 2

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
于 2012-04-26T03:32:15.510 回答
1

您有一个GROUP_CONCAT()聚合函数,但没有使用GROUP BY子句,因此您的结果将是一行。

请注意,在 MySQL 中,允许使用 aGROUP BY仅指定一列,而列表中会出现更多SELECT列,但这不能移植到其他 RDBMS。因此,我第二次加入以连接该表中b10g_entries的所有其他列,同时仅使用.idGROUP BY

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;
于 2012-04-26T03:33:04.353 回答