Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Warunek łączenia Oracle z Top 1

Nadal nie wiem, który rekord w twoim przykładzie chciałeś, więc pozwól, że przedstawię ci kilka alternatyw.

Z Twojego zgłoszenia problemu wywnioskowałem, że chcesz mieć najnowszą datę wejścia w życie tych dostępnych. Ponieważ w grę wchodzą remisy, nie możesz użyć max() (jak już wspomniałeś) i row_number() jest droga do zrobienia:

with cte as (
  select
    addrid, effectdt, xpirdt,
    row_number() over (partition by addrid order by effectdt desc) as rn
  from addrdata
)
select
  addrid, effectdt, xpirdt
from cte
where rn = 1

W następnej części zgubiłeś mnie z wartościami null... Jeśli sortowanie wtórne odbywa się według daty wygaśnięcia i chcesz, aby wartość null przewyższała ostatnią datę wygaśnięcia, możesz uporządkować według daty wygaśnięcia i najpierw umieścić nulls first :

with cte as (
  select
    addrid, effectdt, xpirdt,
    row_number() over 
        (partition by addrid order by effectdt desc, xpirdt nulls first) as rn
  from addrdata
)
select
  addrid, effectdt, xpirdt
from cte
where rn = 1

Co oznacza, że ​​ten rząd jest zwycięzcą:

10948448    5/14/2015   <null>

Jeśli jednak chcesz, aby wartości null były uwzględniane tylko wtedy, gdy nie ma dat wygaśnięcia, możesz użyć nulls last (lub pomiń, ponieważ jest to ustawienie domyślne):

with cte as (
  select
    addrid, effectdt, xpirdt,
    row_number() over
        (partition by addrid order by effectdt desc, xpirdt nulls last) as rn
  from addrdata
)
select
  addrid, effectdt, xpirdt
from cte
where rn = 1

Oznacza to, że ten facet wygrał nagrodę:

10948448    5/14/2015   5/13/2015

Ponieważ używa to row_number() nie stracisz żadnych wierszy — każdy wiersz ma swój numer. Tyle tylko, że jeśli są prawdziwe remisy, to jest sednem, który rząd zostanie wybrany. Jednak Twój problem z zerowymi datami ważności nie powinien powodować żadnych problemów przy takim podejściu.

-- edytuj 13.02.16 --

Chyba zaczynam aby zrozumieć Twój problem, ale nie jestem w 100% pewien. Dołączyłem fragmenty kodu z lewym złączeniem z moją sugestią i potrzebą najpierw zerowych dat wygaśnięcia, a to jest moje kolejne pęknięcie:

with cte as (
  select
    addrid, effectdt, xpirdt,
    row_number() over 
        (partition by addrid order by effectdt desc, xpirdt nulls first) as rn
  from addrdata
)
select
  cte.addrid, effectdt, xpirdt
from
  mbr_person mb
  left join partyxref px on
    mb.nameid = px.nameid and
    px.reftype = 'COMM'
  left join cte on
    px.refkey = cte.addrid and
    cte.rn = 1

Zakładając, że to nie wystarczy:

  1. Kiedy mówisz, że null XPIRDT ma pierwszeństwo – czy masz na myśli nawet nowsze daty efektywne, czy jest to tylko rozstrzygnięcie dla ostatniego EFFECTDT? Jeśli to drugie, to to, co mam, powinno działać. Jeśli to pierwsze, to musimy zmienić kolejność według w funkcji analitycznej
  2. Całkowicie zgaduję, jeśli chodzi o partyxref i mbr_person tabele. Jeśli to nie wystarczy, może opublikuj kilka przykładowych danych i pożądane dane wyjściowe, aby uwzględnić te dwie tabele, lub pobaw się?



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Data Oracle Między zapytaniem

  2. W ramach procedury PL/SQL umieść zapytanie lub refcursor w tabeli HTML

  3. Oracle SQL Connect według logiki

  4. Perl DBI - uruchom skrypt SQL z wieloma instrukcjami

  5. Najszybszy sposób na wstawienie miliona wierszy w Oracle