我使用Postgres解析一些数据。我在名为Congress的数据库中有一个名为
person_roles
的SQL表。此person_roles
表包含以下列:
person_id(每个ID都是一个独特的人),
类型(参议员或代表),
start_date(此人开始在大会上发球的日期,例如1789-03-04或2015-01-06),
end_date(此人在大会上结束的日期,例如1791-03-03,或者例如2021-01-03),
州(美国政府在此期间为此人服务)
党(民主党人,共和党人和许多其他党派;请注意,从1789年到2015年,共有4228人,其党派既不是民主党也不是共和党人。)
我想解析这个SQL表并获得以下输出。然后我想将这样的结果导出到csv文件。
我想要的输出表应该包含以下列:
年份(从1789年开始到2015年结束:1789年,1790年,......,2014年,2015年)
所有州每年民主党人(参议员和代表)总人数(或人数)
所有州每年共和党人(参议员和代表)的数量(或统计数字)
其他方的数量(或数量)'所有州每年都有人(参议员和代表)
从1789年到2015年有227年,我想要的输出表应该有227行。
请注意,每年,例如1996年,只要一个人的start_date在今年或今年之前(例如< = 1996-12-31),他/她的end_date是在今年或今年之后(例如> = 1996-01-02)和他/她的start_date< = end_date,那么这个人将被算作在今年(例如1996年)服务的国会议员。
我知道如何在此表中查找特定年份的民主党人或共和党人或其他缔约方的人数。基本上,例如,如果我在congress =#
中键入以下命令SELECT COUNT(*) AS numberdem
FROM person_roles
WHERE party = 'Democrat'
AND start_date <= '1996-12-31'
AND end_date >= '1996-01-02'
AND start_date <= end_date;
然后我会得到结果:
numberdem
----------------
251
(1 row)
同样,如果我输入以下命令:
SELECT COUNT(*) AS numberrep
FROM person_roles
WHERE party = 'Republican'
AND start_date <= '1996-12-31'
AND end_date >= '1996-01-02'
AND start_date <= end_date;
然后我会得到结果:
numberrep
----------------
291
(1 row)
如果我输入:
SELECT COUNT(*) AS numberother
FROM person_roles
WHERE party <> 'Republican'
AND party <> 'Democrat'
AND start_date <= '1996-12-31'
AND end_date >= '1996-01-02'
AND start_date <= end_date;
然后我会得到结果:
numberother
-----------------
2
(1 row)
但是,我不知道如何获得一个包含4列的结果表,其中第1列给出了年份(每年从1789年到2015年),第2列给出了每个特定民主党人的数量(numberdum)从1789年到2015年,第3列给出了从1789年到2015年每个特定年份的共和党人数(numberrep),第4列给出了从1789年到2015年每个特定年份的其他缔约方(数量等)的数量。最后,我想导出227行的SQL输出表(因为从1789年到2015年有227年)和4列到csv文件。
如何使用SQL命令实现此类任务?如果此任务对SQL不耐用,我应该从表person_roles导出所有数据并将其导出到Excel csv并解析该Excel文件吗?
答案 0 :(得分:2)
你基本上想要复制他们所服务的每一年的人,然后将其分组,这样你就可以计算每年的人数。然后,要将计数转换为列,您可以对查找要计数的值的条件语句求和。类似的东西:
select
year,
sum(case when party = 'Republican' then 1 else 0 end) as republicans,
sum(case when party = 'Democrat' then 1 else 0 end) as democrats,
sum(case when party <> 'Republican' and party <> 'Democrat' then 1 else 0 end) as other
from person_roles p
join generate_series(1789,2015) as s(year)
on year between date_trunc('year', start_date)
and date_trunc('year', end_date)
group by year;