在聚合查询中计算具有特定条件的行

Posted

技术标签:

【中文标题】在聚合查询中计算具有特定条件的行【英文标题】:Count rows with a specific condition in aggregate query 【发布时间】:2012-03-12 18:41:14 【问题描述】:

我有这个查询来获得PlayerSessions 和reconnect = TRUE 的数量,按Player.country 分组:

SELECT
    country,
    COUNT(*) AS with_reconnect
FROM PlayerSession S LEFT JOIN Player P ON (P.id = S.player_id)
WHERE reconnect = TRUE
GROUP BY country

我想修改它以不仅显示重新连接的会话计数,还显示总计数,例如:

SELECT
    country,
    COUNT(*) AS total,
    (COUNT WHERE reconnect = TRUE) AS with_reconnect
FROM PlayerSession S LEFT JOIN Player P ON (P.id = S.player_id)
GROUP BY country

这可能吗?如果可以,正确的语法是什么?

【问题讨论】:

查看***.com/questions/4414539/…了解各种方法 【参考方案1】:
SELECT  Country,
        COUNT(*) AS Total,
        COUNT(CASE WHEN Reconnect = true THEN 1 END) AS With_Reconnect
FROM    PlayerSession S 
        LEFT JOIN Player P 
            ON P.id = S.player_id
GROUP BY country

【讨论】:

非常感谢。从 3 小时开始搜索这个 :)【参考方案2】:
SELECT
    country,
    COUNT(*) AS total,
    sum(case when reconnect = TRUE then 1 else 0 end)  AS with_reconnect
FROM PlayerSession S LEFT JOIN Player P ON (P.id = S.player_id)
GROUP BY country

【讨论】:

【参考方案3】:

以下就足够了

SELECT
    p.country,
    COUNT(*) AS total,
    SUM(IF(s.reconnect=TRUE,1,0)) AS with_reconnect
FROM PlayerSession s

INNER JOIN Player p
ON p.id = s.player_id

GROUP BY p.country

我只是重写了查询。每个 PlayerSession 都会有一个 Player 行,因此将其更改为 INNER JOIN。此外,不需要 CONCAT,因为此查询中总会有 PlayerSession 行(除非没有会话)

【讨论】:

嗯,看来括号不匹配。 抱歉,支架失明,已修复:) 在一次快速测试中,我发现这里显示的 SUM(IF()) 方法比接受答案中显示的 COUNT(CASE) 方法快。【参考方案4】:
SELECT
    country,
    COUNT(CASE WHEN reconnect = TRUE THEN S.player_id ELSE NULL END) AS with_reconnect,
    COUNY(*)
FROM PlayerSession S LEFT JOIN Player P ON (P.id = S.player_id) 
GROUP BY country

【讨论】:

ELSE NULL 是多余的,如果您不指定 ELSE,则结果是 NULL,但是这是相当琐碎的,我喜欢使用 COUNT 而不是 SUM(CASE WHEN ... THEN 1 ELSE 0 END)当期望的结果是计数而不是总和时,所以你得到了我的投票!还要将 COUNY 更改为 COUNT... @GarethD - 我知道这是多余的,但这样更清楚

以上是关于在聚合查询中计算具有特定条件的行的主要内容,如果未能解决你的问题,请参考以下文章

计算具有多个聚合列的行

T-SQL计算具有特定值的行(在一个查询中多个)

聚合具有特定值的两行之间的行

SQL 聚合具有相同 id 的行,辅助列中的特定值

如果我的 PLSQL 块中有多个 DML 查询,我如何计算聚合受影响的行?

计算具有特定文本的行数