Все още не съм наясно кой запис, във вашия пример, искахте, така че нека ви дам някои алтернативи.
От изявлението ви за проблем разбрах, че искате последната ефективна дата от наличните. Тъй като има включени връзки, не можете да използвате max()
(както вече посочихте) и row_number()
е правилният начин:
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
Следващата част беше, когато ме загубихте с нулите... Ако второстепенното ви сортиране е по дата на изтичане и искате нулева стойност да надмине последната дата на изтичане, тогава ще подредите по датата на изтичане и първо ще поставите 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
Което означава, че този ред е печелившият:
10948448 5/14/2015 <null>
Ако обаче искате нули да се считат само ако няма дати на изтичане, можете да използвате nulls last
(или го пропуснете, тъй като е по подразбиране):
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
Това означава, че този човек е спечелил наградата:
10948448 5/14/2015 5/13/2015
Тъй като това използва row_number()
няма да загубите никакви редове -- всеки ред гарантирано има номер на ред. Просто ако има истински равенства, тогава е жребий за това кой ред е избран. Вашият проблем с нулевите дати на валидност обаче не трябва да създава проблеми с този подход.
-- редактиране 13.02.16 --
Мисля, че започвам за да разбера проблема ви, но не съм 100% сигурен. Включих фрагменти от вашия код с лявото съединение с моето предложение и необходимостта първо да има нулеви дати на изтичане и това е следващият ми крак:
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
Ако приемем, че това не го прави:
- Когато казвате, че нулевият XPIRDT има предимство -- имате ли предвид дори над по-скорошни дати на влизане в сила, или това е само тайбрек за най-скорошния EFFECTDT? Ако последното, тогава това, което имам, трябва да работи. Ако първото, тогава трябва да превключим реда по в аналитичната функция
- Напълно се досещам, когато става въпрос за
partyxref
иmbr_person
маси. Ако това не помогне, може би да публикувате някои примерни данни и желан изход за включване на тези две таблици или да го поправите?