在应用程序中,有一个表projects
,categories
和一个表,这些表处理它们之间的n:m
关系(project_category_info
):
现在,我想获取一个类别的所有项目(我正在使用HAVING
解决此问题)。我还需要结果集中的信息,每个项目属于哪些类别(CONCAT_GROUP
和GROUP
组合):
SELECT
`projects`.*,
`categories`.`id` AS `id`,
GROUP_CONCAT(categories.id SEPARATOR '|||') AS `categories`,
GROUP_CONCAT(categories.short_name SEPARATOR '|||') AS `category_names`
FROM
`projects`
INNER JOIN
`project_category_info` ON `project_category_info`.`project_id` = `projects`.`id`
LEFT JOIN
`categories` ON `project_category_info`.`category_id` = `categories`.`id`
GROUP BY
`projects`.`id`
HAVING
(`categories`.`id` = 3)
;
结果集产生13行。但是,当我省略
GROUP_CONCAT
和GROUP
时,我又得到了一行。为什么?什么会导致这种行为? 最佳答案
我开始相信您的逻辑在查询中是错误的。我建议尝试重写它。最好的方法是先退后一步,再将问题分解再解决。
要获得一个类别的所有项目:
SELECT project_id
FROM project_category_info
WHERE category_id = 3;
现在,将其重新连接到category_info表以获取那些项目的所有行:
SELECT *
FROM project_category_info
WHERE project_id IN(
SELECT project_id
FROM project_category_info
WHERE category_id = 3);
您可以将其加入项目和类别以获得名称:
SELECT p.id, p.title, c.title
FROM project_category_info pci
JOIN projects p ON p.id = pci.project_
JOIN categories c ON c.id = pci.catgory_id
WHERE pci.project_id IN(
SELECT project_id
FROM project_category_info
WHERE category_id = 3);
现在,您可以将GROUP_CONAT()添加到
c.title
列,并按p.id进行分组:SELECT p.id, p.title, GROUP_CONCAT(c.short_name SEPARATOR '|||') AS category_names
FROM project_category_info pci
JOIN projects p ON p.id = pci.project_
JOIN categories c ON c.id = pci.catgory_id
WHERE pci.project_id IN(
SELECT project_id
FROM project_category_info
WHERE category_id = 3)
GROUP BY p.id;