Sql 拉入与最接近另一日期的日期关联的值
我有两张桌子。第一个是个人列表(ID)和交易日期。第二个是客户历史记录表,其中包含一段时间内客户数据的快照。我感兴趣的是在最接近交易日期但在交易日期之前的运行日期中加入会员标志 *编辑:我尝试使用TOP 1,并在/partition上排名。。。但它们运行的时间太长了。我无权在表上创建索引。这就是我所需要的查询:Sql 拉入与最接近另一日期的日期关联的值,sql,sql-server,Sql,Sql Server,我有两张桌子。第一个是个人列表(ID)和交易日期。第二个是客户历史记录表,其中包含一段时间内客户数据的快照。我感兴趣的是在最接近交易日期但在交易日期之前的运行日期中加入会员标志 *编辑:我尝试使用TOP 1,并在/partition上排名。。。但它们运行的时间太长了。我无权在表上创建索引。这就是我所需要的查询: SELECT t1.*, t2.RunDate, t2.CST_ISMEMBER FROM table1 t1 INNER JOIN table2 t2 ON t1.ID=t
SELECT t1.*, t2.RunDate, t2.CST_ISMEMBER
FROM table1 t1
INNER JOIN table2 t2
ON t1.ID=t2.ID
AND t2.RunDate =
(SELECT MAX(t2b.RunDate)
FROM table2 t2b
WHERE t2b.ID=t2.ID AND t1.TransDate >= t2b.RunDate)
更多编辑*我发现,对于表1中的大约9K个人,表2中的运行日期发生在事务日期之后。所以现在我需要找到最接近交易的日期(之前或之后)。努力寻找一个datediff解决方案,它不涉及排名/分区或排名1,这给了我缺乏索引的问题。我不得不在5分钟后终止查询,这样我就不会被它吼叫;-)
这些是表2中最大的可用索引
预期结果:
ID TransDate IsMember
1 8/20/13 N
2 9/5/14 Y
最好的方法是什么
提前感谢。相关子查询是一种简单的方法。下面是代码的样子:
select t1.*,
(select top (1) t2.ismember
from table2 t2
where t2.id = t1.id and t2.rundate < t1.transdate
order by t2.rundate desc
) as ismember
from table1 t1;
我怀疑对联合数据的
lag()
比修复第一种方法的任何尝试都要快。但是,使用适当的索引,第一种方法会快得多。您使用的是哪种DBMS产品?“SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加@kiki1113。您应该使用表中可用的索引编辑问题。@GordonLinoff-更新为包含索引。谢谢谢谢-这似乎是有效的;然而,这需要相当长的时间来处理。作为参考,表1有8932行,表2有16806807行。有没有办法提高跑步所需的时间,还是仅仅因为sunch有一张大桌子让它跑完。外部表格参考应该是table1
,而不是table2
(这是一个打字错误)。我还添加了有关索引的信息,并修复了SQL Server的语法。@Gordon Linoff,很遗憾,我没有创建索引的权限。我找到了一个替代方法,它使用子查询选择ID匹配的最大运行日期,事务日期>=运行日期。。。但我刚刚发现,对于9K记录,t2中的记录是在交易日期之后创建的。。。所以现在我需要修改。编辑上面的更多细节。谢谢你-这是更快,让我到我需要的。我同意你的意见。必须让w/IT找出原因。我不知道自从我在7分钟后杀了它之后,“top 1”版本会是什么样子。您提供的第二个备选方案在30秒内运行:-)谢谢!
select t1.*,
(select top (1) t2.ismember
from table2 t2
where t2.id = t1.id and t2.rundate < t1.transdate
order by t2.rundate desc
) as ismember
from table1 t1;
with t as (
select id, transdate as dte, null as ismember, 1 as which
from table1
union all
select id, rundate, ismember, 2
from table2
)
select t.*
from (select t.*, lag(ismember) over (partition by id order by dte, which desc) as ismember
from t
) t
where which = 1;