Postgres where子句超过两列

时间:2017-09-26 11:22:55

标签: sql postgresql subquery where-clause

数据库 - 我正在使用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”的表中

我正在按阶段形成如下查询。

  1. 选择延迟超过15分钟的机场

    从ontime选择origin,year,count(*)as depdelay_count     哪里     depdelay> 15个
        按年份分组,来源     按depdelay_count desc排序     )

  2. 现在我希望每年只排出前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;

  3. 现在我已经通过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)         按来源分组         按原产地排序;

  4. 如果我通过添加年份中的年份

    来修改第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年的所有年份,我想避免。

    请您帮助优化查询,以便我可以选择所有年份的数据,而无需手动选择每年。

1 个答案:

答案 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;

注意使用条件聚合和使用具有聚合函数的窗口函数。