简体   繁体   English

我的 group_concat SQL 查询有什么问题?

[英]What's wrong with my group_concat SQL query?

I have three tables:我有三张表:

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

And i'm trying to get first 25 blog entries with their tags (that's why I use many-to-many relationship) using this query:我正在尝试使用以下查询获取前 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;

But I only get one record back.但我只取回了一张唱片。 What's wrong with this query?这个查询有什么问题?

Add a GROUP BY clause.添加GROUP BY子句。

Now, you're getting a list of ALL tags found anywhere in the set.现在,您将获得在集合中任何位置找到的所有标签的列表。 Instead, you only want the ones within the group (by entry).相反,您只需要组内的那些(按条目)。

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

You have a GROUP_CONCAT() aggregate function, but have not used a GROUP BY clause, so your result will be one row.您有一个GROUP_CONCAT()聚合函数,但没有使用GROUP BY子句,因此您的结果将是一行。

Note that in MySQL it is permissible to use a GROUP BY with only one column specified while many more appear in the SELECT list, but that is not portable to other RDBMS.请注意,在 MySQL 中,允许使用仅指定一列的GROUP BY ,而更多列出现在SELECT列表中,但这不能移植到其他 RDBMS。 So instead, I have joined b10g_entries in a second time to connect all the other columns from that table, while only using the id in the GROUP BY .因此,我第二次加入b10g_entries以连接该表中的所有其他列,同时仅使用GROUP BYid

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM