如何为以下内容创建mysql查询?

时间:2009-12-10 23:16:42

标签: mysql join

我有以下查询:

SELECT m.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM comic_series AS m
JOIN chapters as c on c.comic_id = m.id
WHERE m.title_en = 'test'

这允许我通过给出漫画的名称来从漫画书中找到章节。该查询选择comic_series表中的所有列,并添加chapters(该漫画的章节数)和latest_chapter(最新章节)列。

现在,这个问题困扰了我很长一段时间:

我有第三列,其中包含链接到类别ID的漫画ID(类别详细信息位于第四个表格中,但这里不相关),我想通过搜索来选择漫画书及其章节类别ID。

这是我到目前为止所提出的:

SELECT `m`.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id 
JOIN chapters as c on c.comic_id = m.id
where mc.category_id = 5
GROUP BY `m`.`id`

这会返回正确的COUNT(c.chapter_nr)但是当我添加更多类别ID时,它会返回错误的数量:

SELECT `m`.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id 
JOIN `chapters` as c on c.comic_id = m.id
where mc.category_id = 5 OR mc.category_id = 1
GROUP BY `m`.`id`

上面的查询应该为COUNT(c.chapter_nr)返回1,但它返回2.这可能是因为comic_categories表中有2条记录用于该漫画,而chapters中只有1条记录} table。

3 个答案:

答案 0 :(得分:1)

根据您的查询,您选择的所有漫画书的category_id为5 AND 1.由于此处无法实现,因此您无法获得任何结果。将其更改为OR或更好的IN子句:

SELECT `m`.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id 
JOIN chapters as c on c.comic_id = m.id
where mc.category_id IN (1, 5) -- <<<<< HERE
GROUP BY `m`.`id`
编辑(修改后的问题之后):

使用JOIN,您的结果会爆炸。我假设,漫画有多个类别,因此您可以获得每个类别的结果。

在不进行分组的情况下尝试使用该语句,以便在总结之前掌握实际使用的内容:

SELECT `m`.*
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id
JOIN chapters as c on c.comic_id = m.id
where mc.category_id IN (1, 5);

这将为您提供两行,但结果非常相似(最可能完全相同的两行)。

您可以使用子选择解决此问题,如

SELECT `m`.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN chapters as c on c.comic_id = m.id
where m.id IN (SELECT comic_id FROM comic_categories WHERE category_id IN (1, 5))
GROUP BY `m`.`id`;

这将返回您的期望。这有一个陷阱:一旦数据库显着增长,Subselect与IN语法配对可能会非常慢。因此,请确保在您的网站经常访问后立即将其保留在内存中!

答案 1 :(得分:1)

您应该使用OR代替AND

SELECT `m`.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id 
JOIN chapters as c on c.comic_id = m.id
where mc.category_id IN (1, 5)
GROUP BY `m`.`id`

编辑:下面的子查询将解决错误的计数。它们是在comic_series属于多个类别时引起的。然后,连接将导致重复的行。子查询没有这个问题。

SELECT m.*, COUNT(c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM comic_series AS m
JOIN chapters as c on c.comic_id = m.id
WHERE m.id IN 
(
  SELECT comic_id 
  FROM comic_categories 
  WHERE category_id IN (1, 5)
)

答案 2 :(得分:1)

当您加入类别表时,每个匹配类别会获得一行。如果漫画分为两类,您将获得重复的行数。

请尝试使用COUNT(DISTINCT c.chapter_nr)

SELECT `m`.*, COUNT(DISTINCT c.chapter_nr) as chapters, MAX(c.chapter_nr) as latest_chapter
FROM `comic_series` AS `m`
JOIN `comic_categories` AS `mc` ON mc.comic_id = m.id 
JOIN `chapters` as c on c.comic_id = m.id
where mc.category_id = 5 OR mc.category_id = 1
GROUP BY `m`.`id`