T-SQL - 按最近日期和GROUPED BY ID选择

时间:2011-01-10 17:38:42

标签: sql sql-server sql-server-2005 tsql

根据以下数据,我需要使用SQL Server 2005为每个链接ID选择最接近指定日期的记录:

ID     Date      Linked ID
...........................
1    2010-09-02     25
2    2010-09-01     25
3    2010-09-08     39
4    2010-09-09     39
5    2010-09-10     39
6    2010-09-10     34
7    2010-09-29     34
8    2010-10-01     37
9    2010-10-02     36
10   2010-10-03     36

因此,使用01/10/2010选择它们应该返回:

1    2010-09-02     25 
5    2010-09-10     39
7    2010-09-29     34 
8    2010-10-01     37
9    2010-10-02     36

我知道这一定是可能的,但似乎无法绕过它(必须太接近一天结束:P)如果有人可以帮助或给我一个正确的方向推动它会非常感谢!

编辑:此外,我遇到过这个sql来获取最近的日期:

abs(DATEDIFF(minute, Date_Column, '2010/10/01'))

但无法弄清楚如何正确地合并到查询中......

由于

3 个答案:

答案 0 :(得分:8)

你可以试试这个。

DECLARE @Date DATE = '10/01/2010';

WITH cte AS
    (
    SELECT ID, LinkedID, ABS(DATEDIFF(DD, @date, DATE)) diff,
        ROW_NUMBER() OVER (PARTITION BY LinkedID ORDER BY ABS(DATEDIFF(DD, @date, DATE))) AS SEQUENCE
    FROM MyTable
    )

SELECT *
FROM cte
WHERE SEQUENCE = 1
ORDER BY ID
;

您没有说明如何处理LinkedID组中的多行代表最接近目标日期的情况。此解决方案仅包含一行。在这种情况下,您无法保证包含多个有效值中的哪一行。

如果要包含代表最接近值的所有行,可以在查询中使用RANK()更改ROW_NUMBER()。

答案 1 :(得分:4)

您希望按天查看DATEDIFF函数(http://msdn.microsoft.com/en-us/library/ms189794.aspx)的绝对值。

查询可能看起来像这样(未经测试)

with absDates as 
(
   select *, abs(DATEDIFF(day, Date_Column, '2010/10/01')) as days
   from table
), mdays as
( 
   select min(days) as mdays, linkedid
   from absDates
   group by linkedid
)
select * 
from absdates
inner join mdays on absdays.linkedid = mdays.linkedid and absdays.days = mdays.mdays

答案 2 :(得分:0)

您也可以尝试在select语句中使用子查询:

select  [LinkedId],
        (select top 1 [Date] from [Table] where [LinkedId]=x.[LinkedId] order by abs(DATEDIFF(DAY,[Date],@date)))
from    [Table] X
group by [LinkedId]