【问题标题】:Group by 3-month period按 3 个月期间分组
【发布时间】:2013-09-26 22:11:14
【问题描述】:

我在 Oracle 中创建了一个选择,它返回机组人员每月的过夜停留次数(如果有的话):

CRE_ALPHA  CRE_NAME  MONTH  YEAR  NIGHT_STOPS  
---------- --------- ------ ----- ------------
AAC        Adinda    6      2013  8  
AAC        Adinda    7      2013  9  
AAC        Adinda    8      2013  2  
AAC        Adinda    9      2013  7  
AAC        Adinda    10     2013  4  
CCU        Cristiano 6      2013  5  
CCU        Cristiano 7      2013  6  
CCU        Cristiano 8      2013  3  
CCU        Cristiano 9      2013  11
CVA        Carine    7      2013  9
CVA        Carine    9      2013  10
CVA        Carine    10     2013  10

现在,每 3 个月有 18 晚停留的限制。因此,我想按连续 3 个月有 > 18 晚停留的时间进行分组。结果应该是这样的:

CRE_ALPHA  CRE_NAME  TIMESPAN        NIGHT_STOPS
---------- --------- --------------- ------------
AAC        Adinda    6/2013-8/2013   19
AAC        Adinda    7/2013-9/2013   18
CCU        Cristiano 7/2013-9/2013   20
CVA        Carine    7/2013-9/2013   19
CVA        Carine    8/2013-10/2013  20

请注意,如果一个月的夜间停留次数为零,则没有行,但我想要 3 个月的结果,包括 0 的结果。

有人可以帮忙吗?

如果有帮助,请在下面完整选择:


ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MM-YYYY hh24:mi:ss';
SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, Maand, Jaar, count(*) "Night stops"
FROM
  (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code, dst, det, dsa, (dst - Prev_end_time) * 1440 stop_over, EXTRACT(MONTH FROM dst) Maand, EXTRACT(YEAR FROM dst) Jaar
  FROM
    (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code, dst, dsa, det, dea, LAG(det) OVER (ORDER BY cre_alpha, dst) Prev_end_time
    FROM
      (SELECT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code,
      COALESCE(flt_mvt_db, flt_com_dep_blk, pog_std, gco_start, oth_std, rsv_std) as dst,
      COALESCE(flt_mvt_ab, flt_com_arr_blk, pog_sta, gco_end, oth_sta, rsv_sta) as det,
      COALESCE(flt_apt_iata_code_dep, pog_apt_iata_code_from, gco_apt_iata_code, rsv_apt_iata_code) as dsa,
      COALESCE(flt_apt_iata_code_arr, pog_apt_iata_code_to, gco_apt_iata_code, rsv_apt_iata_code) as dea
      FROM
        (SELECT DISTINCT cre_id, cre_alpha, cre_first_name, cre_last_name, pos_crb_iata_code
        FROM master.crews, master.assignments, master.positions
        WHERE asg_pos_id = pos_id AND asg_cre_id = cre_id AND asg_d_type <> 'LEA' 
        AND asg_start_time BETWEEN '01-JUN-2013' AND '01-NOV-2013'
        ORDER BY cre_alpha) tab1, master.assignments
      FULL OUTER JOIN master.flights ON master.assignments.asg_flt_id = master.flights.flt_id
      FULL OUTER JOIN master.positionings ON master.assignments.asg_pog_id = master.positionings.pog_id
      FULL OUTER JOIN master.ground_courses ON master.assignments.asg_gco_id = master.ground_courses.gco_id
      FULL OUTER JOIN master.other_duties ON master.assignments.asg_oth_id = master.other_duties.oth_id
      FULL OUTER JOIN master.reserves ON master.assignments.asg_rsv_id = master.reserves.rsv_id
      WHERE asg_d_type <> 'LEA' AND asg_d_type <> 'STP' AND asg_cre_id = tab1.cre_id
      AND asg_start_time BETWEEN '01-JUN-2013' AND '02-NOV-2013' AND asg_actif = 'Y'
      ORDER BY cre_alpha, asg_start_time)
    )
  WHERE pos_crb_iata_code <> dsa
  AND EXTRACT(DAY FROM dst) - EXTRACT(DAY FROM Prev_end_time) >= 1)
WHERE stop_over > 240
GROUP BY cre_id, cre_alpha, cre_first_name, cre_last_name, Maand, Jaar
ORDER BY cre_alpha;

【问题讨论】:

    标签: sql date count oracle11g group-by


    【解决方案1】:

    您可以使用分析函数来实现您想要的。基于您当前的查询,它是这样的:

    select *
    from (
        select cre_alpha, cre_name,
        month month_end, year year_end,
        sum(night_stops) over (
            partition by cre_alpha, cre_name
            order by year * 12 + month
            range between 2 preceding and current row
        ) as night_stops
        from (
          ... your current query ...
        ) t
    ) m
    where night_stops >= 18
    

    注意:

    • 查询返回 3 个月期间的结束(年/月)。您还必须扩展它以打印周期的开始。
    • 我使用条件&gt;= 18 来匹配您的输出,即使文本显示它是&gt; 18
    • windowing 子句range between 2 preceding and current row 和order by 子句year * 12 + month 确保采用三个月的窗口,而不仅仅是三个连续的行。如果您的基本查询中缺少月份,这很重要。

    玩得开心。

    【讨论】:

    • year * 12 + month 订购与month 订购有何不同? make sure a three month window is taken and not just three consecutive rows怎么会?
    • 如果所有行都来自同一年,那么您只能使用month 而不是year * 12 + month。但如果他们来自不同的年份,那么重要的是,例如2012 年 12 月和 2013 年 1 月被分配了连续的数字,因此您可以正确应用加窗条款。
    • 啊哈!那么它是有道理的。
    猜你喜欢
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 2013-11-28
    • 2019-04-10
    • 2013-04-05
    相关资源
    最近更新 更多