Oracle
 sql >> база данни >  >> RDS >> Oracle

Условие за присъединяване към Oracle с Топ 1

Все още не съм наясно кой запис, във вашия пример, искахте, така че нека ви дам някои алтернативи.

От изявлението ви за проблем разбрах, че искате последната ефективна дата от наличните. Тъй като има включени връзки, не можете да използвате 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

Ако приемем, че това не го прави:

  1. Когато казвате, че нулевият XPIRDT има предимство -- имате ли предвид дори над по-скорошни дати на влизане в сила, или това е само тайбрек за най-скорошния EFFECTDT? Ако последното, тогава това, което имам, трябва да работи. Ако първото, тогава трябва да превключим реда по в аналитичната функция
  2. Напълно се досещам, когато става въпрос за partyxref и mbr_person маси. Ако това не помогне, може би да публикувате някои примерни данни и желан изход за включване на тези две таблици или да го поправите?



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да получите израз за създаване на таблица на Oracle в SQL*Plus

  2. Свържете се с Oracle DB от Spring-jdbc с удостоверяване на Oracle Wallet

  3. Как да добавя клъстер към съставен ключ?

  4. Как да разберете броя на цифрите на числото на оракула

  5. Как да внедрим този тригер на Oracle SQL?