【问题标题】:SQL GROUP BY/COUNT even if no resultsSQL GROUP BY/COUNT 即使没有结果
【发布时间】: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;

我做错了什么?

【问题讨论】:

    标签: sql mysql


    【解决方案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 子句)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      相关资源
      最近更新 更多