【问题标题】:Select values among duplicates, that dont' have maximum value in one columns(Oracle)在重复项中选择值,在一列中没有最大值(Oracle)
【发布时间】:2019-09-02 06:49:32
【问题描述】:

假设我有行:

123123  2019-07-23 22:00:00 9999-12-31 00:00:00
123123  2019-07-23 22:00:00 2019-07-04 00:00:00
123123  2019-07-23 22:00:00 2019-07-05 00:00:00
123123  2019-07-25 04:05:06 9999-12-31 00:00:00
123123  2019-07-25 04:05:06 2019-07-04 00:00:00
123123  2019-07-25 04:05:06 2019-07-05 00:00:00

您可以观察到,前两列中有重复项(前三行,然后是另外 3 行)

我想Group by 前两列(让我们称它们为:col1 and col2)使用具有子句(having Count(col1)>1)并选择第三列中没有最大值(每个组)的所有行。

所以在这种情况下应该选择它:

123123  2019-07-23 22:00:00 2019-07-04 00:00:00
123123  2019-07-23 22:00:00 2019-07-05 00:00:00
123123  2019-07-25 04:05:06 2019-07-04 00:00:00
123123  2019-07-25 04:05:06 2019-07-05 00:00:00

我如何在 Oracle 中做到这一点?

【问题讨论】:

  • 为什么不直接过滤:col3 TO_DATE('9999-12-31 00:00:00', 'YYYY-MM-DD hh24:mi:ss')?跨度>

标签: sql oracle


【解决方案1】:

怎么样?

select  * from(
select col1,col2,col3,row_number() over (partition by col1,col2 order by col3 desc) rn from a
) where rn>1

【讨论】:

    【解决方案2】:

    我的理解方式:

    SQL> with test (id, col1, col2) as
      2    (select 123123, to_date('23.07.2019 22:00', 'dd.mm.yyyy hh24:mi'), to_date('31.12.9999 00:00', 'dd.mm.yyyy hh24:mi') from dual union all
      3     select 123123, to_date('23.07.2019 22:00', 'dd.mm.yyyy hh24:mi'), to_date('04.07.2019 00:00', 'dd.mm.yyyy hh24:mi') from dual union all
      4     select 123123, to_date('23.07.2019 22:00', 'dd.mm.yyyy hh24:mi'), to_date('05.07.2019 00:00', 'dd.mm.yyyy hh24:mi') from dual union all
      5     --
      6     select 123123, to_date('25.07.2019 04:05', 'dd.mm.yyyy hh24:mi'), to_date('31.12.9999 00:00', 'dd.mm.yyyy hh24:mi') from dual union all
      7     select 123123, to_date('25.07.2019 04:05', 'dd.mm.yyyy hh24:mi'), to_date('04.07.2019 00:00', 'dd.mm.yyyy hh24:mi') from dual union all
      8     select 123123, to_date('25.07.2019 04:05', 'dd.mm.yyyy hh24:mi'), to_date('05.07.2019 00:00', 'dd.mm.yyyy hh24:mi') from dual
      9    )
     10  select id, col1, col2
     11  from (select id, col1, col2,
     12               row_number() over (partition by id, col1 order by id, col1 desc, col2 desc) rn
     13        from test
     14       )
     15  where rn > 1
     16  order by id, col1, col2;
    
            ID COL1             COL2
    ---------- ---------------- ----------------
        123123 2019-07-23 22:00 2019-07-04 00:00
        123123 2019-07-23 22:00 2019-07-05 00:00
        123123 2019-07-25 04:05 2019-07-04 00:00
        123123 2019-07-25 04:05 2019-07-05 00:00
    

    或者(更糟糕的是,它会从同一个表中提取两次)

     <snip>
     10  select * from test t
     11  where (t.id, t.col1, t.col2) not in
     12        (select t1.id, max(t1.col1), max(t1.col2)
     13         from test t1
     14         where t1.id = t.id
     15         group by t1.id, t1.col1
     16        )
     17  order by t.id, t.col1, t.col2;
    
            ID COL1             COL2
    ---------- ---------------- ----------------
        123123 2019-07-23 22:00 2019-07-04 00:00
        123123 2019-07-23 22:00 2019-07-05 00:00
        123123 2019-07-25 04:05 2019-07-04 00:00
        123123 2019-07-25 04:05 2019-07-05 00:00
    
    SQL>
    

    【讨论】:

      【解决方案3】:

      我认为其他答案不正确,因为它们没有明确检查最大日期。

      您可以通过以下方式获得最简单的结果:

      select t.*
      from t
      where t.col3 <> '9999-12-31 00:00:00';
      

      我需要假设您确实希望要求存在最大日期(因为您在查询中提到了这个特定值)并且然后您需要其他行。为此,我认为exists 可能是合适的:

      select t.*
      from t
      where t.col3 <> '9999-12-31 00:00:00' and
            exists (select 1
                    from t t2
                    where t2.col1 = t.col1 and
                          t2.col2 = t.col2 and
                          t2.col3 = '9999-12-31 00:00:00'
                   );
      

      你也可以用窗口函数来表达这个:

      select t.*
      from (select t.*, max(col3) over (partition by col1, col2) as max_col3
            from t
           ) t
      where max_col3 = '9999-12-31 00:00:00' and
           col3 <> '9999-12-31 00:00:00';
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-03
        相关资源
        最近更新 更多