在 MySQL / SQL 中获取同一行的条件计数

发布于 2024-10-18 14:54:24 字数 623 浏览 2 评论 0原文

假设我有一个表 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

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

IE,

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

Suppose I have a table, Foo, that looks like this:

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

If I wanted to get a list of the number of males and females per team on the same row, how would I do that?

I know I could do SELECT COUNT(Name) as "#", Team, Gender FROM foo GROUP BY Team, Gender, and that's fine for most purpose.

But that would give me 2 rows per team, like below, and that can be a pain.

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

How could I structure the query such that they appear on the same row?

ie,

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼眸里的那抹悲凉 2024-10-25 14:54:24
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(当性别=“男性”时选择点,否则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
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

For the comment

Imagine now that each row has an arbitrary numeric score associated with it, in a Score column. How would I have 'Male points' and 'Female points? Would that be SUM(case when gender="male" then select points else 0 end) "Male Points"

You're close. The answer is

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
待"谢繁草 2024-10-25 14:54:24

我正在寻找的模式是自连接;在我看来,语法和逻辑比 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 语句,而是被拆分为同一个表的自己的副本。然后,您将男性玩家表与团队中的女性玩家表合并,然后按团队进行分组。

The pattern I was looking for was a Self-Join; the syntax and logic is, in my mind, more elegant then the CASE pattern.

Specifically,

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

Instead of case statements, the groupings I want in different columns get split into their own copies of the same table. You then join the table of Male players with a Table of Female players on the Team, and then group by the Team.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文