【问题标题】:SQL (Oracle) to query for record with max date, only if the end_dt has a valueSQL (Oracle) 查询具有最大日期的记录,仅当 end_dt 具有值时
【发布时间】:2015-11-12 22:05:11
【问题描述】:

我试图通过查看开始日期和结束日期从一行中选择一条记录。我需要做的是选择最大开始日期,如果结束日期有值,则只返回该最大日期的结果。

我希望下面的图片有助于进一步澄清这一点。这是在基于 Oracle 的 SQL 中。

示例 #2

到目前为止,我可以在场景 #2 中返回所有记录或错误地返回记录,但我还没有找到完成这项工作的最佳方法。我会非常感谢任何帮助。

谢谢!

【问题讨论】:

    标签: sql oracle date select max


    【解决方案1】:

    我会使用解析函数:

    with sample_data as (select 1 id, 1 grp_id, to_date('01/01/2015', 'dd/mm/yyyy') st_dt, to_date('23/01/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 2 id, 1 grp_id, to_date('24/02/2015', 'dd/mm/yyyy') st_dt, to_date('15/02/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 3 id, 1 grp_id, to_date('17/03/2015', 'dd/mm/yyyy') st_dt, to_date('30/03/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 4 id, 2 grp_id, to_date('01/01/2015', 'dd/mm/yyyy') st_dt, to_date('17/01/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 5 id, 2 grp_id, to_date('21/01/2015', 'dd/mm/yyyy') st_dt, to_date('23/03/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 6 id, 2 grp_id, to_date('14/04/2015', 'dd/mm/yyyy') st_dt, to_date('16/05/2015', 'dd/mm/yyyy') ed_dt from dual union all
                         select 7 id, 2 grp_id, to_date('28/05/2015', 'dd/mm/yyyy') st_dt, null ed_dt from dual),
                 res as (select id,
                                grp_id,
                                st_dt,
                                ed_dt,
                                max(st_dt) over (partition by grp_id) max_st_dt
                         from   sample_data)
    select id,
           grp_id,
           st_dt,
           ed_dt
    from   res
    where  st_dt = max_st_dt
    and    ed_dt is not null;
    
    
            ID     GRP_ID ST_DT      ED_DT     
    ---------- ---------- ---------- ----------
             3          1 17/03/2015 30/03/2015
    

    【讨论】:

    • 它不起作用的情况是最大日期为空..在这种情况下(grp 2)它不应该返回任何东西。在这种情况下,它会返回第二高的日期。
    • 啊,我明白了。我误解了要求。明天我回来工作时必须看看这个,但它很容易修复 - 将 case 语句从获取 max_start_date 的分析函数中取出,然后在外部添加“and ed_dt is not null”查询。
    【解决方案2】:

    这将是最简单的方法之一。

    select * from
    (
    select apay_id,
           max(start_dt) OVER () max_start_dt,
            start_dt,
           end_dt
    from sample
    )
    where
    start_dt=max_start_dt
    and end_dt is not null
    

    想法是获得最大的 start_dt 和相应的 end_dt。 如果 end_dt 为空,则过滤结果。

    SQL Fiddle

    数据库架构

    create table sample
    (apay_id number(7),
     account_number number(7),
     start_dt date,
     end_dt date);
    

    样本1

     insert into sample values(554433, 123456, '15-Aug-15', null);
     insert into sample values(112266, 123456, '21-Jul-15', '31-Aug-15');
     insert into sample values(733221, 123456, '29-Jun-15', '31-Jul-15');
    

    Sample1 的输出

    No rows
    

    样本2

     insert into sample values(554433, 123456, '15-Aug-15', '11-Nov-15');
     insert into sample values(112266, 123456, '21-Jul-15', '31-Aug-15');
     insert into sample values(733221, 123456, '29-Jun-15', '31-Jul-15');
    

    Sample2 的输出

    | APAY_ID |             MAX_START_DT |                     END_DT |
    |---------|--------------------------|----------------------------|
    |  554433 | August, 15 2015 00:00:00 | November, 11 2015 00:00:00 |
    

    【讨论】:

    • 只有当空记录是第一个时它似乎才有效。我将 null 移到最后,它在不应该有的时候返回了一个值。 sqlfiddle.com/#!4/35b68/1
    • 更正解决方案
    【解决方案3】:

    select * from (select apay_id from sample where end_dt is not null order by start_dt desc) where rownum=1

    我认为这也可以。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-13
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      相关资源
      最近更新 更多