如何编写一个SQL查询,它将返回一个项目的所有类别?

时间:2010-08-24 21:09:22

标签: sql mysql

我有一个SQL查询:

SELECT b . * , CONCAT( GROUP_CONCAT( c.name ) ) categories, CONCAT( GROUP_CONCAT( c.id ) ) cids
FROM books b
JOIN categories_of_books cb ON b.id = cb.book_id
JOIN categories c ON c.id = cb.category_id
GROUP BY b.id

它以类别为所有类别的书籍和 cids 所有类别ID返回给我。

当我添加像这样的WHERE子句时:

WHERE c.id = 10

类别中,我只有一个类别,很明显。但是我怎样才能编写SQL查询,它将以强制条件返回类别别名中的所有类别的书籍:

WHERE c.id = 10

[编辑1]

只有变体:

SELECT b . * , GROUP_CONCAT( c.name ) categories, GROUP_CONCAT(CAST(c.id AS CHAR)) cid
FROM books b
JOIN categories_of_books cb ON b.id = cb.book_id
JOIN categories c ON c.id = cb.category_id
WHERE b.id in (SELECT categories_of_books.book_id FROM categories_of_books join categories on categories_of_books.category_id = categories.id WHERE categories.id = 10)
GROUP BY b.id

你知道其他更好的变种吗?

1 个答案:

答案 0 :(得分:1)

你要求的是什么,基本上(如果我正确地解释了你的要求):

  • 对于books表中的所有记录,返回一行
  • 如果图书分配了多个类别,则列categories包含“category_1,category_2,category3”,即所有类别名称的串联
  • 仅当其中一个类别为categories.id = 10

您需要做的是首先选择ID = 10的所有图书:

SELECT cb.book_id 
FROM   categories_of_books cb
WHERE  cb.category_id = 10

现在你想要所有书籍都在那个子集中:

SELECT b.*
FROM   books b
WHERE  b.id IN
(
    SELECT cb.book_id 
    FROM   categories_of_books cb
    WHERE  cb.category_id = 10
)

现在您可以将其转换回复杂的分组查询:

SELECT b.*, 
       CONCAT(GROUP_CONCAT(c.name)) categories, 
       CONCAT(GROUP_CONCAT(c.id)) cids
FROM   books b
JOIN   categories_of_books cb 
       ON b.id = cb.book_id
JOIN   categories c 
       ON c.id = cb.category_id
WHERE  b.id IN
(
    SELECT cb.book_id 
    FROM   categories_of_books cb
    WHERE  cb.category_id = 10
)
GROUP BY b.id

实际上,我没有想到更简洁/更简单的方法。顺便说一句,值得花时间使用空白来创建代码,因为通常认为这种方式更容易阅读,未来必须维护代码的任何人都可能会感谢你=)