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 即使没有结果的主要内容,如果未能解决你的问题,请参考以下文章
java中如何实现mysql中的group by order by count()功能
提高性能 union all+group by+order by+count