【问题标题】:Pulling in value associated with a date that closest to another date提取与最接近另一个日期的日期关联的值
【发布时间】:2020-02-20 06:00:18
【问题描述】:

我有 2 张桌子。第一个是个人 (ID) 列表和交易日期。第二个是客户历史记录表,其中包含客户数据随时间变化的快照。我有兴趣为最接近但在交易日期之前的运行日期提取会员标志。

* 编辑:我尝试使用 TOP 1,并排名超过/分区...但它们运行时间太长。我无权在表上创建索引。这是我需要的查询:

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 中的运行日期发生在交易日期之后。所以现在我需要找到最接近(之前或之后)交易的日期。努力寻找不涉及排名超过/分区或前 1 的 datediff 解决方案,因为我缺乏索引问题。我不得不在 5 分钟后终止查询,这样我才不会被 IT 大喊大叫;-) 这些是表 2 中最大的可用索引。

    TABLE 1 
ID   TransDate 
1    8/20/13
2    9/5/14

TABLE 2
ID   RunDate      IsMember
1    6/30/2010    Y
1    7/11/2012    N
1    7/30/2013    N
1    8/15/2013    Y
2    9/1/2014     Y
2    9/10/2014    N 

想要的结果:

ID  TransDate   IsMember
1   8/20/13     N
2   9/5/14      Y

解决这个问题的最佳方法是什么?

提前致谢。

【问题讨论】:

  • 您使用的是哪种 DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加tagWhy should I tag my DBMS
  • @kiki1113 。 . .您应该使用表格上可用的索引来编辑您的问题。
  • @GordonLinoff - 更新为包含索引。谢谢!

标签: sql sql-server


【解决方案1】:

关联子查询是一种简单的方法。下面是代码的样子:

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;

为了提高性能,您需要在table2(id, rundate, ismember) 上建立索引。

编辑:

你有糟糕的索引。这个历史表如何在id 上没有索引很奇怪。这是使用窗口函数的完全不同的方法。

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;

我怀疑联合数据上的lag() 将比修复第一种方法的任何尝试更快。但是,使用适当的索引,第一个会更快。

【讨论】:

  • 谢谢 - 这似乎工作;但是,它需要相当长的时间来处理。作为参考,表 1 有 8,932 行,表 2 有 16,806,807 行。有没有办法改善运行所需的时间,还是只是为了让它运行一个大桌子 2 的本质?
  • @kiki1113 。 .外部表引用应该是table1 而不是table2(这是一个错字)。我还添加了有关索引的信息并修复了 SQL Server 的语法。
  • @Gordon Linoff,很遗憾我无权创建索引。我找到了一个替代方法,它使用子查询选择 ID 匹配的 MAX 运行日期,并且事务日期 >= 运行日期......但我刚刚发现对于 9K 记录,t2 中的记录是在交易日期...所以现在我需要修改。在上面进行编辑以获取更多详细信息。
  • 谢谢 - 这更快,让我得到了我需要的东西。我同意你对索引的看法。必须与 IT 合作才能找出原因。
  • 不确定“前 1”版本会如何,因为我在 7 分钟后将其杀死。您提供的第二个替代方案在不到 30 秒内运行 :-) 谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-25
  • 2022-10-05
  • 2017-04-28
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多