我有一个名为Players的下表:
name | memberof | country | givento | cardtype
Ni 1 Australia 7 red
Ju 1 Australia 9 yellow
Is 1 Australia 11 red
Ji 3 Japan 2 red
Su 3 Japan 22 red
Sa 3 Japan 25 yellow
Ji 3 Japan 2 yellow
Ji 3 Japan 2 yellow
Li 4 Thailand 13 red
Li 4 Thailand 13 yellow
Ro 1 Australia null null
So 2 Malaysia null null
上表显示了球员和他们在足球比赛中收到的卡片。 名称是指玩家的名称,memberof是团队的ID,国家/地区是玩家所属的国家/地区,给定是玩家的ID,卡类型可以是红色或黄色。
我正在尝试编写一个查询,以确定每个国家/地区收到的红卡和黄卡的总数。如果一个国家/地区的玩家之一收到一张卡片,则该国家/地区将被视为收到卡片。
查询的输出应为:
teams | reds | yellows
Australia 2 1
Malaysia 0 0
Japan 2 3
Thailand 1 1
我有以下两种观点,分别给出了每个国家/地区收到的黄牌和红牌的总数:
create or replace view yellow as select memberof, country, cardtype,
count(cardtype) over (partition by country)
as yellows from Players where cardtype = 'yellow';
create or replace view red as select memberof, country, cardtype,
count(cardtype) over (partition by country)
as reds from Players where cardtype = 'red';
通过对上述两个查询的“ memberof”结果集执行内部联接,我可以获得一个国家收到的红卡和黄卡的总数。
select distinct y.country, r.reds, y.yellows from yellow y inner join red r on
y.memberof = r.memberof;
但是,在输出中不包括获得零红卡和零黄卡的马来西亚。
country | reds | yellows
Australia 2 1
Japan 2 3
Thailand 1 1
对于收到两种颜色的零色卡的国家,我该如何计算红色和黄色色卡?任何见解都会受到赞赏。
答案 0 :(得分:4)
使用filter
并计划聚合:
select p.country,
count(*) filter (where p.carttype = 'red') as reds,
count(*) filter (where p.carttype = 'yellow') as yellows
from players p
group by p.country;
您的带有两个视图和窗口函数的方法似乎很复杂。
答案 1 :(得分:0)
这是简单的条件聚合:
select
country,
sum(case when cardtype = 'red' then 1 else 0 end) reds,
sum(case when cardtype = 'yellow' then 1 else 0 end) yellows
from players
group by country
答案 2 :(得分:0)
我喜欢戈登的回答,尽管另一种选择是总结一个案例陈述。如果您需要兼容性,这可能会有所帮助,尽管我认为这会占用更多资源。
SELECT country,
SUM(
CASE WHEN cardtype = 'red' OR cardtype = 'yellow' THEN 1
ELSE 0
END
) AS CardCount
FROM players
GROUP BY country