【问题标题】:Getting conditional counts on to the same row in MySQL / SQL在 MySQL / SQL 中对同一行进行条件计数
【发布时间】:2011-02-23 22:58:24
【问题描述】:

假设我有一张桌子,Foo,看起来像这样:

ID  | Name  | Gender  | Team
1   | Bob   | Male    | A
2   | Amy   | Female  | A
3   | Cat   | Female  | B
4   | Dave  | Male    | B
5   | Evan  | Male    | B

如果我想获得每个团队同一行的男性和女性人数列表,我该怎么做?

我知道我可以做到SELECT COUNT(Name) as "#", Team, Gender FROM foo GROUP BY Team, Gender,这对于大多数用途来说都很好。

但这会让我每个团队有 2 行,如下所示,这可能会很痛苦。

#  Team Gender
1 | A | Male
1 | A | Female
1 | B | Female
2 | B | Male

如何构造查询以使它们出现在同一行上?

即,

Team | Males | Females
A    |   1   | 1
B    |   2   | 1

【问题讨论】:

    标签: mysql sql group-by


    【解决方案1】:
    select team,
     SUM(case when gender='Male' then 1 else 0 end) Male,
     SUM(case when gender='Female' then 1 else 0 end) Female
    from tbl
    group by team
    

    为了评论

    现在想象一下,每一行都有一个与之关联的任意数字分数,在分数列中。我将如何获得“男性积分”和“女性积分”?那会是SUM(当gender =“male”然后选择点其他0结束的情况)“男性点”

    你已经接近了。答案是

    select team,
     SUM(case when gender='Male' then 1 else 0 end) Male,
     SUM(case when gender='Male' then points else 0 end) `Male Points`,
     SUM(case when gender='Female' then 1 else 0 end) Female,
     SUM(case when gender='Female' then points else 0 end) `Female Points`
    from tbl
    group by team
    

    【讨论】:

    • 我会接受,但我意识到我错过了我的问题中的一个细节:想象一下,现在每一行都有一个与之关联的任意数字分数,在分数列中。我将如何获得“男性积分”和“女性积分”?那会是SUM(case when gender="male" then select points else 0 end) "Male Points"吗?
    【解决方案2】:

    我正在寻找的模式是 Self-Join;在我看来,语法和逻辑比 CASE 模式更优雅。

    具体来说,

    SELECT Males.Team, COUNT(Males.id) as "Males", SUM(Males.Points) as "Male Points", 
           COUNT(Females.id) as "Females", SUM(Females.Points) as "Female Points" 
    FROM scores as Males 
    LEFT JOIN scores as Females ON Males.Team=Females.Team AND Females.Gender="Female" 
    WHERE Males.Gender="Male" 
    GROUP BY Team
    

    我想要在不同列中的分组被拆分为同一个表的自己的副本,而不是 case 语句。然后,您将男性玩家表与团队中的女性玩家表一起加入,然后按团队分组。

    【讨论】:

    • 至于逻辑比理查德的“更容易掌握”,我认为这是非常主观的。我了解这两种解决方案的工作原理,但我的大脑对 Richard 的基于 CASE 的解决方案感觉更舒服。这并不是说您的答案是错误的或不是那么好。我只是说并不是每个人都会同意两种解决方案中的哪一种更直观。
    • @ean5533 好点。编辑它以反映这一点。我也想知道性能。我猜想,但不知道,JOIN 方法更快,因为过滤只在 JOIN 时发生一次,而不是在每个 CASE 语句中发生,尽管可以想象 SQL 引擎可以为此进行优化。
    • 性能也是我考虑的一件事。我只知道 SQL 性能调优的基础知识,所以我也不知道哪个查询会更快;它可能严重依赖于 DBMS。我确实知道,如果 TEAM 不是索引列,那么连接将非常缓慢。但是,如果使用适当的索引,我的直觉是 join 方法会更快。
    猜你喜欢
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 2021-08-30
    • 2017-09-06
    • 2018-11-10
    • 2021-02-04
    • 1970-01-01
    • 2017-05-27
    相关资源
    最近更新 更多