T-SQL-按最近日期选择并按ID分组

T-SQL-按最近日期选择并按ID分组,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,从下面的数据中,我需要使用SQL Server 2005为每个链接ID选择最接近指定日期的记录: 因此,使用2010年10月1日选择它们应返回: 我知道这一定是可能的,但我似乎无法改变我的想法,因为这一天已经快结束了:p如果有人能帮助我或在正确的方向上轻轻推我一下,我将不胜感激 编辑:我还遇到了以下sql以获取最接近的日期: abs(DATEDIFF(minute, Date_Column, '2010/10/01')) 但无法找出如何正确地合并到查询中 谢谢您想查看DATEDIFF函数的绝对

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

因此,使用2010年10月1日选择它们应返回:

我知道这一定是可能的,但我似乎无法改变我的想法,因为这一天已经快结束了:p如果有人能帮助我或在正确的方向上轻轻推我一下,我将不胜感激

编辑:我还遇到了以下sql以获取最接近的日期:

abs(DATEDIFF(minute, Date_Column, '2010/10/01'))
但无法找出如何正确地合并到查询中


谢谢

您想查看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
你可以试试这个

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组中的多行表示最接近目标日期的情况。此解决方案将只包含一行,在这种情况下,您无法保证包含多个有效值中的哪一行


如果要包含表示最接近值的所有行,可以在查询中更改带有秩的行号。

您也可以尝试在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]

@Hogan啊,是的,我已经看到了,但是在问题中忘了提到,所以我更新了它。谢谢你的提醒that@w69rdy:添加了示例查询。示例查询可能不正确-应该是mindays,否则您将返回最大的差异,对吗?另外,我认为这方面的表现不会很好。一般来说,我建议使用行数解决方案。它应该更直接、更高效。@Hogan,您的查询现在失败了。表absdays的定义在哪里?@bobs:不是:D我修正了输入错误。添加。。。您在我的评论之后添加了编辑。好的,我将为您编写完整的查询。您的标题有误导性,它可能是select ID order by nearest Date您的示例使用MINUTION作为datediff的第一个参数可能不起作用,因为您在示例日期中没有时间。您想使用day-可以缩写为day、dd或d。有趣的是,所有的答案都使用了不同的缩写。@dvhh不,我不这么认为,我在描述我想做的事情,如果你看霍根的答案,这正是他所做的。这比我的查询更好,只有一个选择,但我的可能对初学者更清楚……更多关于行数的信息可以在这里找到:@Hogan-我不确定我是否同意。如果您打算使用CTE,那么您最好利用Row_编号。谢谢您的回答。重复项是不相关的,只要它返回一个就行了need@Thomas:是的,如果你看到我对@Sean答案的评论,我基本上也这么说了,并投了你的票。哇,这是def。最低性能-每个LinkedIn都有一个选择。是的,它只适用于小表
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
;
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]