给定这两个表:
Goals(Id,Player,isAuto)
Players(Id,Name,Team)
我想知道每个团队的总进球数和自动进球数。
到目前为止我的查询:
SELECT p.Team,COUNT(g.Id) AS Total,COUNT(g.isAuto) AS Auto
FROM Players p
JOIN Goals g
ON p.Id=g.Player
WHERE g.isAuto=True
GROUP BY p.Team
这个查询的问题是 isAuto
的条件影响第一个 COUNT
函数的结果,我不知道如何使它成为 isAuto
上的条件只影响相应的 COUNT
。
答案 0 :(得分:2)
SELECT p.Team
, COUNT(g.Id) AS Total
, COUNT(CASE WHEN g.isAuto = True THEN 1 END) AS Auto
FROM Players p
JOIN Goals g
ON p.Id=g.Player
GROUP BY p.Team
;
注意:对于我们希望显示没有目标的球员/球队的情况,请使用外连接。否则,内连接没问题。
答案 1 :(得分:1)
这个查询的问题是 isAuto 的条件影响了第一个 COUNT 函数的结果,我不知道怎么做,所以 isAuto 上的条件只影响相应的 COUNT。
聚合函数的结果是在 FROM
子句指定的源中满足通过 WHERE
子句指定的任何条件的行上计算的。您可以将其视为在将行聚合到计算聚合函数的组之前由 WHERE
条件过滤的行。您不能让 WHERE
子句仅应用于所选聚合函数的适当子集。
但是还有其他方法可以计算您想要获得的结果。特别是,如果 goals.isauto
是一个整数字段,仅限于包含值 0
和 1
,那么您可以确定 SUM(g.isauto)
而不是 COUNT(g.isauto)
:
SELECT p.Team,COUNT(g.id) AS Total, SUM(g.isAuto) AS Auto
FROM Players p
JOIN Goals g
ON p.Id=g.Player
WHERE g.isAuto=True
GROUP BY p.Team
如果 isauto
的域是别的东西,那么您可以计算 CASE
或其他执行适当转换的表达式的总和。例如,SUM(CASE WHEN g.isAuto > 0 THEN 1 ELSE 0 END)
。
还要注意 COUNT(g.id)
计算组中具有非空 g.id
的行数,但如果 g.id
是一个不可为空的主键,那么它总是全部行,更清楚地表示为 COUNT(*)
。