Tabela zamówień

Status_id Order_number 
100        ord1 
200        ord2 
100        ord3 
300        ord2 
100        Ord4 
400        ord2 
200        ord1
200        ord3

Potrzebuję wszystkich zamówień, które są z Status_id=100 lub 200, ale jeśli te same zamówienia mają Status_id=400, nie należy go wybrać. W powyższym przykładzie należy wybrać ord1 ord3, ord4. Ale Ord2 nie należy wybrać, ponieważ jest również z status_id=400.

0
Devadas Wagle 15 luty 2017, 17:56

2 odpowiedzi

Najlepsza odpowiedź

Jest to rodzaj problemu, który jest łatwo rozwiązany za pomocą group by i having:

select order_number
from orders
group by order_number
having sum(case when status in (100, 200) then 1 else 0 end) > 0 and
       sum(case when status = 400 then 1 else 0 end) = 0;
2
Gordon Linoff 15 luty 2017, 15:14

Jeśli potrzebujesz pełnych szczegółów każdego wiersza, a nie tylko numerów zamówień, musisz użyć funkcji analitycznych, a nie agregatów; W tym przypadku warunkowe liczenie analityczne na wiersze, gdzie test_data=400.

with
     test_data ( status_id, order_number ) as (
       select 100, 'ord1' from dual union all 
       select 200, 'ord2' from dual union all  
       select 100, 'ord3' from dual union all 
       select 300, 'ord2' from dual union all 
       select 100, 'ord4' from dual union all 
       select 400, 'ord2' from dual union all 
       select 200, 'ord1' from dual union all 
       select 200, 'ord3' from dual
     )
-- end of test data (not part of the query); SQL query begins below this line
select   status_id, order_number
from     ( select status_id, order_number,
                  count(case when status_id = 400 then 1 end)
                             over (partition by order_number) as st_400_cnt
           from   test_data
         )
where    status_id in (100, 200)
  and    st_400_cnt = 0
order by order_number, status_id   --  if needed
;

STATUS_ID ORDER_NUMBER
--------- ------------
      100 ord1
      200 ord1
      100 ord3
      200 ord3
      100 ord4

5 rows selected.
2
mathguy 15 luty 2017, 20:27