T-SQL – SELECT par date la plus proche et GROUPED BY ID

À partir des données ci-dessous, je dois sélectionner l'logging le plus proche d'une date spécifiée pour chaque ID lié à l'aide de SQL Server 2005:

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 

Donc les sélectionner en utilisant 01/10/2010 devrait returnner:

 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 

Je sais que cela doit être possible, mais je n'arrive pas à le contourner (il doit être trop près de la fin de la journée: P) Si quelqu'un peut m'aider ou me pousser doucement dans la bonne direction, ce serait grandement apprécié !

EDIT: Aussi, je suis tombé sur ce sql pour get la date la plus proche:

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

mais ne pouvait pas comprendre comment intégrer dans la requête correctement …

Merci

tu peux essayer ça.

 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 ; 

Vous n'avez pas indiqué comment gérer le cas où plusieurs lignes d'un groupe LinkedID représentent le plus proche de la date cible. Cette solution n'inclura qu'une ligne Et, dans ce cas, vous ne pouvez pas garantir quelle rangée des multiples valeurs valides est incluse.

Vous pouvez modifier ROW_NUMBER () avec RANK () dans la requête si vous souhaitez inclure toutes les lignes qui représentent la valeur la plus proche.

Vous voulez regarder la valeur absolue de la fonction DATEDIFF (http://msdn.microsoft.com/en-us/library/ms189794.aspx) par jours.

La requête peut ressembler à ceci (non testé)

 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 

Vous pouvez également essayer de le faire avec une sous-requête dans l'instruction 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]