SQL在其他表中获取特定日期的最近行

时间:2014-03-19 08:55:59

标签: sql sql-server

有一张桌子TAB_A

  ID  |    Date    |   Value  
--------------------------------
  101 | 2014-03-01 | 101000001
  101 | 2014-03-03 | 101000003
  101 | 2014-03-06 | 101000006
  102 | 2014-03-01 | 102000001
  103 | 2014-03-01 | 103000001

例如,另一个表TAB_B中的这条记录:

    ID  |    Date    |  TAB_A.Id 
-----------------------------------
  40002 | 2014-03-05 |     101 

我需要获得最接近(最最近TAB_A.ValueTAB_B.Date字段(在这种情况下为'101000003'并且不是'101000006')。

我一直在寻找类似场景的其他回复(例如this one),但这不是我需要的。

有什么建议吗?在此先感谢您的帮助。

编辑:我忘了提及TAB_A有超过200K的记录而TAB_B有超过55M的记录。

5 个答案:

答案 0 :(得分:5)

看到标签是sql-server,Limit将不起作用。相反,使用顶部

 SELECT TOP 1 ID, Date, Value 
 FROM TAB_A 
 WHERE Date < (SELECT Date from TAB_B where ID=40002) 
 ORDER BY Date DESC

 SELECT  ID, Date, Value 
 FROM tab_a
 WHERE date=
 (SELECT MAX(date) 
  FROM TAB_A 
  WHERE Date < 
     (SELECT Date 
    FROM TAB_B 
    WHERE ID=40002)
 )

如果您只想在上一次查询中获得1个结果,请使用DISTINCT。例如,如果您要查找的日期是2014-03-01,则第二个查询将显示3个示例,不同的仅为1.在第一个查询中,top 1已确保您只有1个结果

编辑:更新以下评论:

SELECT b.id, b.date, a.value FROM
    (SELECT TOP 1 ID, Date, Value 
     FROM TAB_A 
     WHERE Date < (SELECT Date from TAB_B B where ID=40002) 
     ORDER BY Date DESC) a
     ,
     (SELECT id,date,[TAB_A.id] FROM tab_b )b
     WHERE a.id=b.[TAB_A.id]

请原谅我的大写字母/小写字母不一致......

答案 1 :(得分:1)

SELECT ID, Date, Value 
FROM TAB_A 
WHERE Date < (SELECT Date from TAB_B where ID=40002) 
ORDER BY Date DESC LIMIT 1

首先,您在子查询中从TAB_B中选择所需的日期。然后从TAB_B中选择所有这些早于此的日期(如果需要,可以修改为&lt; =)。然后按日期降序并选择TOP 1(最高的一个)。我认为你也可以使用MAX(但我不确定)。

答案 2 :(得分:1)

试试这个:

SELECT TOP 1 * FROM (
SELECT A.ID,A.Value, MIN(DATEDIFF(day,A.Date,B.Date)) as MinDiff
FROM TAB_A A, TAB_B B
GROUP BY A.ID,A.Value ) as T 
WHERE MinDiff>0
ORDER BY MinDiff

结果:

ID    VALUE       MINDIFF
101   101000003   2

请参阅SQL Fiddle中的结果。

<强>解释

内部查询将选择ID,值和最小日期差异。使用外部查询,我们可以选择最小日期差异大于0的记录。

答案 3 :(得分:0)

以下代码将显示给定条件的第一条记录。在您的情况下,它将返回您需要的内容..!

SELECT Value 
  FROM TAB_A 
  WHERE DATE < (SELECT Date from TAB_B WHERE ID= '40002') and ROWNUM <= 1 
  ORDER BY DATE;

答案 4 :(得分:0)

你应该在tab_a中有一个日期索引,这样才能很好地执行(需要sqlserver 2008 +):

declare @tab_a table(id int, Date date, value int)
insert @tab_a values (101,'2014-03-01',101000001),
(101,'2014-03-03',101000003),(101,'2014-03-06',101000006),
(102,'2014-03-01',102000001),(103,'2014-03-01',103000001)

declare @tab_b table(id int, Date date, tab_a_id int)
insert @tab_b
values
(  40002, '2014-03-05', 101 ), (  40002, '2014-03-02', 101 )

select b.ID, b.Date bdate, x.Date adate, x.value
from @tab_b b
outer apply
(select top 1 value, date
from @tab_a a
where a.date <= b.date
and a.id = b.TAB_A_Id
order by a.date desc
) x

结果:

ID    bdate       adate     value
40002 2014-03-05 2014-03-03 101000003
40002 2014-03-02 2014-03-01 101000001