A列中的Duplicate / muliple值希望根据B列中的值仅拉出1行

时间:2018-01-30 18:58:57

标签: sql oracle

假设我有一个包含两列,即订单和状态的表。我想每个订单只拉1行,但可能有多行具有不同的状态。例如,如果我有以下行:

   Order   Status
1) 1111    Cold
2) 1111    Warm
3) 2222    Warm
4) 2222    Cold
5) 3333    Cold
6) 3333    Cold

我如何编写一个只返回的查询:

2) 1111 Warm
3) 2222 Warm
5 or 6) 3333 Cold

因此,我希望在状态列(暖>冷)上使用优先级,并且每个订单只拉1行。

4 个答案:

答案 0 :(得分:0)

以下是使用row_number()的一种方法:

select t.*
from  (select t.*,
              row_number() over (partition by order by instr('Warm,Cold', status) as seqnum
       from t
      ) t
where seqnum = 1;

这使用instr()来确定状态的优先级。这要求状态不完全重叠。因此,它可以添加“热”,但不是“不冷不热”。 (它可以很容易地调整,也可以使用case。)

答案 1 :(得分:0)

好吧,如果你不关心采取哪一个(在这个例子中,你选择按字母顺序选择 last 一个),这样的事情可能会起作用。

SQL> with test (c_order, status) as
  2  (select 1111, 'cold' from dual union all
  3   select 1111, 'warm' from dual union all
  4   select 2222, 'warm' from dual union all
  5   select 2222, 'cold' from dual union all
  6   select 3333, 'cold' from dual union all
  7   select 3333, 'cold' from dual
  8  )
  9  select c_order, max(status) status
 10  from test
 11  group by c_order
 12  order by c_order;

   C_ORDER STAT
---------- ----
      1111 warm
      2222 warm
      3333 cold

SQL>

答案 2 :(得分:0)

查看此代码

create table test ( 
myOrder   number(10),
Status varchar2(10)
);

insert into  test values (  1111 , 'Cold');
insert into  test values(  1111 , 'Warm');
insert into  test values(  2222 , 'Warm');
insert into  test values(  2222 , 'Cold');
insert into  test values(  3333 , 'Cold');
insert into  test values(  3333 , 'Cold');
commit;

select myOrder, max(status) status
   from test 
   group by myOrder
   order by decode ( Status ,'Warm',1, 'Cold',2);

解码()in"顺序由"优先使用状态列(暖>冷)

答案 3 :(得分:0)

只是用你没有要求的东西来扩展你的问题:)

我在数据集中添加了seq列。现在让我们说规则是按照orderid的顺序每seq获取第一行。如果有两行具有相同的seq(与orderid 3333有两行,seq = 1),则决胜局将采用最大状态。 (可能在此示例中,您只需将recno添加到order by,但语法需要聚合函数,即使它对结果没有影响。)

with demo (recno, orderid, status, seq) as
     ( select 1,  1111, 'Cold', 1 from dual union all
       select 2,  1111, 'Warm', 2 from dual union all
       select 3,  1111, 'Warm', 3 from dual
       union all
       select 4,  2222, 'Warm', 3 from dual union all
       select 5,  2222, 'Warm', 2 from dual union all
       select 6,  2222, 'Cold', 1 from dual
       union all
       select 7,  3333, 'Cold', 1 from dual union all
       select 8,  3333, 'Warm', 1 from dual union all
       select 9,  3333, 'Cold', 2 from dual union all
       select 10, 3333, 'Cold', 3 from dual )
select orderid
     , min(recno) keep (dense_rank first order by seq) as recno
     , max(status) keep (dense_rank first order by seq) as status
from   demo
group by orderid;

结果:

   ORDERID      RECNO STATUS
---------- ---------- ------
      1111          1 Cold
      2222          6 Cold
      3333          7 Warm

按照order by然后orderid的顺序扩展seq以获得recno的第一行:

with demo (recno, orderid, status, seq) as
     ( select 1,  1111, 'Cold', 1 from dual union all
       select 2,  1111, 'Warm', 2 from dual union all
       select 3,  1111, 'Warm', 3 from dual
       union all
       select 4,  2222, 'Warm', 3 from dual union all
       select 5,  2222, 'Warm', 2 from dual union all
       select 6,  2222, 'Cold', 1 from dual
       union all
       select 7,  3333, 'Cold', 1 from dual union all
       select 8,  3333, 'Warm', 1 from dual union all
       select 9,  3333, 'Cold', 2 from dual union all
       select 10, 3333, 'Cold', 3 from dual )
select orderid
     , min(recno) keep (dense_rank first order by seq, recno) as recno
     , max(status) keep (dense_rank first order by seq, recno) as status
from   demo
group by orderid;

结果:

   ORDERID      RECNO STATUS
---------- ---------- ------
      1111          1 Cold
      2222          6 Cold
      3333          7 Cold