数据库 - 我正在使用Postgres 9.6.5
我正在分析美国机场管理局(RITA)关于航班到达和离开的数据。 此链接(http://stat-computing.org/dataexpo/2009/the-data.html)列出表中的所有列。
该表有以下29列
无名称描述
1987-2008 1年
2月1-12
3 DayofMonth 1-31
4 DayOfWeek 1(星期一) - 7(星期日)
5 DepTime实际出发时间(本地,hhmm)
6 CRSDepTime预定起飞时间(本地,hhmm)
7 ArrTime实际到达时间(本地,hhmm)
8 CRSArrTime预定到达时间(本地,hhmm)
9 UniqueCarrier唯一载波代码
10 FlightNum航班号
11 TailNum飞机尾号
12 ActualElapsedTime(分钟)
13 CRSElapsedTime以分钟为单位
14分钟的AirTime
15 ArrDelay到达延迟,以分钟为单位
16 DepDelay离开延迟,以分钟为单位
17起源IATA机场代码
18目的地IATA机场代码
19英里距离
20出租车及时出租车,以分钟为单位
21 TaxiOut出租车时间在几分钟
22取消航班被取消了吗?
23取消取消取消原因(A =承运人,B =天气,C = NAS,D =保安)
24 Diverted 1 = yes,0 = no
25分钟的CarrierDelay
26分钟的WeatherDelay
27分钟的NASDelay
28分安全延迟
29 LateAircraftDelay在几分钟内
每年大约有一百万行。
我试图找出计算最繁忙的机场,当延误超过15分钟。 列DepDelay - 具有延迟时间。 origin - 是机场的原始代码。
所有数据都已加载到名为“ontime”的表中
我正在按阶段形成如下查询。
选择延迟超过15分钟的机场
从ontime选择origin,year,count(*)as depdelay_count
哪里
depdelay> 15个
按年份分组,来源
按depdelay_count desc排序
)
现在我希望每年只排出前10个机场 - 我正在做以下工作
选择x.origin,x.year from(子查询为( 从ontime选择origin,year,count(*)as depdelay_count 哪里 depdelay> 15 按年份分组,来源 按depdelay_count desc排序 ) 选择origin,year,rank()over(按depdelay_count desc按年份排序)作为子查询的排名)x其中x.rank< = 10;
现在我已经通过depdelay获得了前10个机场 - 我希望得到这些机场的总机票数。
从原点输入的原点选择原点,计数() (从中选择x.origin(带子查询为( 从ontime选择origin,year,count()作为depdelay_count 哪里 depdelay> 15 按年份分组,来源 按depdelay_count desc排序 ) 选择origin,year,rank()over(按depdelay_count desc按年份排序)作为子查询的排名)x其中x.rank< = 2) 按来源分组 按原产地排序;
如果我通过添加年份中的年份
来修改第3步查询----将是(1987年至2008年)的任何价值
select origin,count(*) from ontime where year = (<YEAR>) origin in
(select x.origin from (with subquery as (
select origin,year,count(*) as depdelay_count from ontime
where
depdelay > 15
group by year,origin
order by depdelay_count desc
)
select origin,year,rank() over (partition by year order by depdelay_count desc) as rank from subquery) x where x.rank <= 2)
group by origin
order by origin;
但我必须手动完成从1987年到2008年的所有年份,我想避免。
请您帮助优化查询,以便我可以选择所有年份的数据,而无需手动选择每年。
答案 0 :(得分:1)
我发现CTE在查询的中间位置令人困惑。您基本上可以使用一个CTE /子查询执行此操作:
with oy as (
select origin, year, count(*) as numflights,
sum( (depdelay > 15)::int ) as depdelay_count,
row_number() over (partition by year order by sum( (depdelay > 15)::int ) desc) as seqnum
from ontime
group by origin, year
)
select oy.*
from oy
where seqnum <= 10;
注意使用条件聚合和使用具有聚合函数的窗口函数。