Sql Oracle与前1的联接条件
我试图找到一个解决方案,包括在我的join中使用row_number()方法,但不知何故无法获得期望的结果 我现在遇到的问题是,我从联接表中有一些记录,这些记录有多个实例(1到多个),具有相同的条件,这会导致重复,因此,即使我认为可以在一个日期使用min()或max(),但具有相同EffectDT的情况会出现两次 除此之外,如果我的实例中没有“活动”记录(XPIRDT不为空),我需要提取过期记录,所以我会使用“或”语句,或者只是执行另一个连接以获取过期记录,如果第一个连接没有生成任何记录,并且在显示之前有一个case条件来计算该值 下面是我正在处理的示例数据: 因此,下面使用上面的数据示例仍然会生成2条记录,我可以通过评估过期日期来消除其中一条记录,但是如果所有记录都过期,则会出现问题,因此无法检索任何内容Sql Oracle与前1的联接条件,sql,oracle,oracle11g,greatest-n-per-group,Sql,Oracle,Oracle11g,Greatest N Per Group,我试图找到一个解决方案,包括在我的join中使用row_number()方法,但不知何故无法获得期望的结果 我现在遇到的问题是,我从联接表中有一些记录,这些记录有多个实例(1到多个),具有相同的条件,这会导致重复,因此,即使我认为可以在一个日期使用min()或max(),但具有相同EffectDT的情况会出现两次 除此之外,如果我的实例中没有“活动”记录(XPIRDT不为空),我需要提取过期记录,所以我会使用“或”语句,或者只是执行另一个连接以获取过期记录,如果第一个连接没有生成任何记录,并且在
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
我还尝试在我的“JOIN”语句中使用以下语句,但是我不知何故无法在这里硬编码了值的语句中使用连接键(REFKEY),因此这确实有效,但似乎无法合并到JOIN语句中
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
我在这件事上浪费了太多的一个小时,所以我需要另外一个人 在你的例子中,我仍然不清楚你想要哪一张唱片,所以让我给你一些选择 我从您的问题陈述中了解到,您需要这些问题的最新生效日期。由于涉及到关系,您不能使用
max()
(如您所述),而row\u 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
下一部分是你失去了我和空。。。如果您的第二次排序是按到期日排序,并且希望空值超过最新的到期日,那么您可以按到期日排序,并将空值放在第一位
:
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>
这意味着这家伙已经得奖了:
10948448 5/14/2015 5/13/2015
由于这使用了row\u number()
您不会丢失任何行,因此保证每行都有一个行号。只是如果真的有关系,那么选择哪一行就有问题了。但是,您的失效日期为空的问题不应导致此方法出现任何问题
--2016年2月13日编辑--
我想我开始理解你的问题了,但我不是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
假设这不起作用:
partyxref
和mbr\u person
表,我完全在猜测。如果这还不能解决问题,可能会发布一些示例数据和包含这两个表所需的输出,或者修改它您错误地使用了
ROW\u NUMBER
函数。您还应该按其他列对数据进行分区(这样,ROW_NUMBER
函数可以按日期对符合某些条件的行进行排序)-例如ROW_NUMBER()(按ADDRID分区,按XPIRD DESC排序)
。最后,类似的densite\u RANK
会起作用。非常感谢,是的,空的XPIRDT将优先于任何其他记录,因为它被认为是“活动”记录,但是如果我没有任何活动记录,我会通过EFFECTDT下一个拉过期记录。根据您的建议,您能否使用ADDRID上的左连接提供语句?我尝试了一些变体,试图在生成记录的子选择中对其进行解释,但不知何故,我一直没有返回任何行,因为我假设在建立行序列之前,行号优先于我尝试检索的记录集。我的第二次尝试已发布。。。在可能的情况下,我有一些潜在的后续问题,这些问题不是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