Jeg er stadig ikke klar over, hvilken post, i dit eksempel, du ønskede, så lad mig give dig nogle alternativer.
Jeg fandt ud af din problemformulering, at du ønsker den seneste ikrafttrædelsesdato for de tilgængelige. Da der er bindinger involveret, kan du ikke bruge max()
(som du allerede har angivet), og row_number()
er vejen at gå:
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
Den næste del var, hvor du mistede mig med nullerne... Hvis din sekundære sortering er efter udløbsdato, og du vil have en nulværdi til at overtrumfe den seneste udløbsdato, så ville du bestille efter udløbsdatoen og sætte 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
Hvilket betyder, at denne række er vinderen:
10948448 5/14/2015 <null>
Hvis du derimod ønskede, at nulls kun skulle tages i betragtning, hvis der ikke er nogen udløbsdatoer, kan du bruge nulls last
(eller udelad det, da det er standard):
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
Det betyder, at denne fyr har vundet prisen:
10948448 5/14/2015 5/13/2015
Da dette bruger row_number()
du vil ikke miste nogen rækker - hver række er garanteret at have et rækkenummer. Det er bare sådan, at hvis der er sande bånd, så er det en kast om, hvilken række der bliver valgt. Dit problem med ugyldige udløbsdatoer burde dog ikke forårsage nogen problemer med denne fremgangsmåde.
-- rediger 13/2/16 --
Jeg tror, jeg starter for at forstå dit problem, men jeg er ikke 100% sikker. Jeg har indarbejdet uddrag af din kode med den venstre joinforbindelse med mit forslag, og behovet for at have ugyldige udløbsdatoer først, og dette er mit næste knæk:
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
Forudsat at dette ikke gør det:
- Når du siger, at en nul XPIRDT har forrang -- mener du endda over nyere effektive datoer, eller er det kun en tiebreaker for den seneste EFFECTDT? Hvis det sidste, så burde det, jeg har, virke. Hvis førstnævnte, så skal vi skifte rækkefølgen efter i den analytiske funktion
- Jeg gætter fuldstændig, når det kommer til
partyxref
ogmbr_person
tabeller. Hvis dette ikke klipper det, kan du måske poste nogle eksempeldata og det ønskede output til at inkludere disse to tabeller, eller rode med det?