I've tried to find a solution to this including the use of the row_number() method within my join, but somehow can't get the desired outcome.
The issue I'm having right now is based on the fact that I have some records from the join table that have multiple instances (1 to many) with the same criteria which is causing duplicates, so even though I thought I could use a min() or max() on a date, the cases where I have the same EffectDT come out twice.
In addition to this, if I have instances where I don't have an "active" record (XPIRDT IS NOT NULL), I need to pull the expired record, so would I use "OR" statement or simply perform another join to get the expired record in the event the first join doesn't produce any record and have a case condition to evaluate the value before display?
So here's an instance of sample data I'm dealing with:
So the following with the above data sample still produces 2 records, which I can eliminate one by evaluating the expiry date, BUT will present problems if all the records are expired so won't retrieve anything.
LEFT OUTER JOIN PARTYXREF
ON MBR_PERSON.NAMEID = PARTYXREF.NAMEID
AND PARTYXREF.REFTYPE LIKE 'COMM'
LEFT JOIN (
SELECT *
FROM ADDRDATA TMP
WHERE TMP.ADDRTYPE = '2'
AND TMP.EFFECTDT = (SELECT MAX(EFFECTDT) FROM ADDRDATA TMP2 WHERE TMP2.ADDRID = TMP.ADDRID)
) MBR_ADDR
ON PARTYXREF.REFKEY = MBR_ADDR.ADDRID
I've also tried using the following within my "JOIN" statement, however I somehow can't make use of the joining key (REFKEY) within where I have the value hardcoded here, so this actually does work, but can't seem to incorporate in the join statement.
SELECT ADDR.*
FROM (SELECT tmp.*, row_number() OVER (ORDER BY XPIRDT DESC) AS SEQNUM
FROM ADDRDATA tmp
WHERE tmp.ADDRTYPE = '2'
AND tmp.ADDRID = 10948448
) ADDR
WHERE SEQNUM = 1
I've wasted one hour too many on this, so I need someone else outlook please! :)
答案 0 :(得分: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
下一部分是你丢失我的空值...如果你的二级排序是到期日,你想要一个空值来胜过最新的到期日期,那么你将在到期日期前订购并放{{ 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
,因此不会丢失任何行 - 每行都保证有行号。只是如果存在真正的联系,那么选择哪一行就是一个折腾。但是,您的null到期日期问题不应该导致此方法出现任何问题。
- 编辑2/13/16 -
我认为我开始了解您的问题,但我并非100%肯定。我已经将你的代码片段与我的建议中的左连接合并,并且首先需要有空的到期日期,这是我的下一个裂缝:
row_number()
假设没有这样做:
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
和partyxref
表。如果这没有削减它,可能会发布一些样本数据和所需的输出以包含这两个表格,或者将其翻转过来?