从一列中选择没有最大值的重复值(Oracle)

时间:2019-09-02 06:49:32

标签: sql oracle

假设我有行:

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

您可以看到,前两列(前三行,然后再三行)中有重复项

我想使用Haveing子句(Group bycol1 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中做到这一点?

3 个答案:

答案 0 :(得分:1)

那怎么样?

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

答案 1 :(得分:1)

我的理解方式:

class C
{
public:
  virtual void func() = 0;
};
template <typename derived>
class B : public C
{
public :
  void func() // cant change to templated return type as virtual function cant be templated
  {
    derived *p = static_cast<derived *>(this);
    p->getData(); // how to return the value from this ?
  }
};

template <typename generic_type>
class A : public B<A<generic_type>>
{
...
};

std::vector<C *> list;
// -------- example -------
// this allows me to do  
C *cp = list.at(0);
cp->func(); // will call getData() indirectly
            // but am unable to get the returned data

或(更糟,因为它两次从同一张表中获取)

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

答案 2 :(得分:0)

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

使用以下方法,您可以最轻松地获得所需的结果:

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';