Oracle
 sql >> Database >  >> RDS >> Oracle

Condizione di unione Oracle con Top 1

Non sono ancora chiaro quale record, nel tuo esempio, volevi, quindi lascia che ti dia alcune alternative.

Ho dedotto dalla tua dichiarazione del problema che desideri l'ultima data di entrata in vigore di quelle disponibili. Dato che ci sono pareggi coinvolti, non puoi usare max() (come hai già affermato) e row_number() è la strada da percorrere:

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

La parte successiva è stata dove mi hai perso con i null... Se il tuo ordinamento secondario è per data di scadenza e vuoi che un valore nullo prevalga sull'ultima data di scadenza, allora ordini per data di scadenza e metti prima 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

Ciò significa che questa riga è la vincitrice:

10948448    5/14/2015   <null>

Se, invece, vuoi che i null siano considerati solo se non ci sono date di scadenza, puoi usare nulls last (o ometterlo, poiché è l'impostazione predefinita):

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

Significa che questo ragazzo ha vinto il premio:

10948448    5/14/2015   5/13/2015

Poiché questo utilizza row_number() non perderai nessuna riga:ogni riga ha un numero di riga garantito. È solo che se ci sono veri pareggi, allora si tratta di scegliere la riga. Tuttavia, il tuo problema con le date di scadenza nulle non dovrebbe causare alcun problema con questo approccio.

-- modifica 13/02/16 --

Penso di iniziare per capire il tuo problema, ma non sono sicuro al 100%. Ho incorporato frammenti del tuo codice con il join sinistro con il mio suggerimento e la necessità di avere prima date di scadenza nulle, e questa è la mia prossima crack:

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

Supponendo che questo non lo faccia:

  1. Quando dici che un XPIRDT nullo ha la precedenza, intendi anche su date di validità più recenti o è solo un tie-break per l'EFFECTDT più recente? Se quest'ultimo, allora quello che ho dovrebbe funzionare. Se il primo, allora dobbiamo cambiare l'ordine per nella funzione analitica
  2. Immagino totalmente quando si tratta di partyxref e mbr_person tavoli. Se ciò non risolve il problema, potresti pubblicare alcuni dati di esempio e l'output desiderato per includere quelle due tabelle o modificarlo?