SQL GROUP BY/COUNT 即使没有结果

Posted

技术标签:

【中文标题】SQL GROUP BY/COUNT 即使没有结果【英文标题】:SQL GROUP BY/COUNT even if no results 【发布时间】:2008-12-23 17:51:30 【问题描述】:

我正在尝试从一个表(游戏)中获取信息,并计算与第一个表中的每个条目相对应的另一个表(门票)中的条目。即使第二个表中没有任何条目,我也希望返回第一个表中的每个条目。我的查询如下:

SELECT g.*, count(*) 
FROM games g, tickets t 
WHERE (t.game_number = g.game_number
   OR NOT EXISTS (SELECT * FROM tickets t2 WHERE t2.game_number=g.game_number))
GROUP BY t.game_number;

我做错了什么?

【问题讨论】:

【参考方案1】:

你需要做一个左连接:

SELECT g.Game_Number, g.PutColumnsHere, count(t.Game_Number) 
FROM games g
LEFT JOIN tickets t ON g.Game_Number = t.Game_Number
GROUP BY g.Game_Number, g.PutColumnsHere

或者,我认为使用相关子查询会更清楚一些:

SELECT g.Game_Number, G.PutColumnsHere,
  (SELECT COUNT(*) FROM Tickets T WHERE t.Game_Number = g.Game_Number) Tickets_Count
FROM Games g

只需确保检查查询计划以确认优化器可以很好地解释这一点。

【讨论】:

非常感谢 - 我有点尴尬,我没有意识到这应该是左连接。 对于不面向集合的思考者来说,子查询可能看起来更清晰,但两种方法之间可能存在一些严重的性能差异。我不是 mysql 专家,所以我不确定,但我至少会在决定之前对两者进行试验。 @Tom:我同意你的看法。在某些情况下,SQL Server 优化器会将其转换为使用 group by 的更有效的左连接。不过,正如您所说,您必须检查查询计划以确保它们运行良好。【参考方案2】:

您需要详细了解如何在 SQL 中使用联接:

SELECT g.*, count(*) 
FROM games g
 LEFT OUTER JOIN tickets t 
 USING (game_number)
GROUP BY g.game_number;

请注意,与某些数据库品牌不同,MySQL 允许您在选择列表中列出许多列,即使您只对它们的主键进行 GROUP BY。只要您的选择列表中的列在功能上依赖 GROUP BY 列,结果是明确的。

如果您在选择列表中列出任何列而不将它们包含在 GROUP BY 或聚合函数中,其他品牌的数据库(Microsoft、Firebird 等)会给您一个错误。

【讨论】:

【参考方案3】:

FROM games g, tickets t”是问题行。这将执行内部连接。任何 where 子句都不能添加到此。我想你想要一个LEFT OUTER JOIN

【讨论】:

查看迈克尔的回复。 (哎哟。被打败了 21 秒。) 逗号语法实际上执行的是笛卡尔连接,而不是内部连接。 好吧,内部连接基本上是一个有限制的笛卡尔连接(ON 子句)

以上是关于SQL GROUP BY/COUNT 即使没有结果的主要内容,如果未能解决你的问题,请参考以下文章

SQL Group By Count 过滤优化

java中如何实现mysql中的group by order by count()功能

提高性能 union all+group by+order by+count

Group by、Count 和 Lambda 表达式

Django 做一个简单的 group by/count 语句

如何在 Django ORM 中执行 GROUP BY ... COUNT 或 SUM?