sql >> Base de Datos >  >> RDS >> Oracle

Condición de unión de Oracle con Top 1

Todavía no tengo claro qué registro, en su ejemplo, quería, así que déjeme darle algunas alternativas.

Deduje de su declaración del problema que desea la última fecha de vigencia de las disponibles. Dado que hay vínculos involucrados, no puede usar max() (como ya dijiste), y row_number() es el camino a seguir:

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 siguiente parte fue donde me perdiste con los nulos... Si tu clasificación secundaria es por fecha de vencimiento y quieres un valor nulo para superar la última fecha de vencimiento, entonces ordenarías por fecha de vencimiento y pondrías 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

Lo que significa que esta fila es la ganadora:

10948448    5/14/2015   <null>

Sin embargo, si desea que los nulos se consideren solo si no hay fechas de vencimiento, puede usar nulls last (u omítalo, ya que es el predeterminado):

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

Lo que significa que este chico ha ganado el premio:

10948448    5/14/2015   5/13/2015

Ya que esto usa row_number() no perderá ninguna fila:se garantiza que cada fila tenga un número de fila. Es solo que si hay vínculos verdaderos, entonces es un sorteo en cuanto a qué fila se elige. Sin embargo, su problema con las fechas de vencimiento nulas no debería causar ningún problema con este enfoque.

-- editar 13/02/16 --

Creo que estoy empezando para entender su problema, pero no estoy 100% seguro. Incorporé fragmentos de su código con la combinación izquierda con mi sugerencia, y la necesidad de tener fechas de vencimiento nulas primero, y esta es mi próxima grieta:

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

Asumiendo que esto no lo hace:

  1. Cuando dice que un XPIRDT nulo tiene prioridad, ¿quiere decir incluso sobre fechas de vigencia más recientes, o es solo un desempate para el EFFECTDT más reciente? Si es lo último, entonces lo que tengo debería funcionar. Si es lo primero, entonces necesitamos cambiar el orden por en la función analítica
  2. Estoy totalmente adivinando cuando se trata de partyxref y mbr_person mesas. Si esto no es suficiente, tal vez publique algunos datos de muestra y el resultado deseado para incluir esas dos tablas, ¿o manipularlo?