T-SQL - получение самой последней даты и самой последней будущей даты - PullRequest
3 голосов
/ 14 июня 2011

Предположим таблицу рекордов ниже

ID    Name       AppointmentDate
--    --------   ---------------
1     Bob         1/1/2010
1     Bob         5/1/2010
2     Henry       5/1/2010
2     Henry       8/1/2011
3     John        8/1/2011
3     John       12/1/2011

Я хочу получить самую последнюю дату встречи по человеку. Поэтому мне нужен запрос, который даст следующий набор результатов.

1   Bob    5/1/2010 (5/1/2010 is most recent)
2   Henry  8/1/2011 (8/1/2011 is most recent)
3   John   8/1/2011 (has 2 future dates but 8/1/2011 is most recent)

Спасибо!

Ответы [ 2 ]

9 голосов
/ 14 июня 2011

Предполагая, что когда вы говорите «самый последний», вы имеете в виду «ближайший», как, например, «сохраненная дата - это наименьшее количество дней от текущей даты, и нам все равно, будет ли она до или после текущей даты», тогда это должен это сделать (может потребоваться тривиальная отладка):

SELECT ID, Name, AppointmentDate
 from (select
           ID
          ,Name
          ,AppointmentDate
          ,row_number() over (partition by ID order by abs(datediff(dd, AppointmentDate, getdate()))) Ranking
         from MyTable) xx
 where Ranking = 1

Используется функция row_number (), начиная с SQL 2005 и выше. Подзапрос «упорядочивает» данные в соответствии со спецификациями, а основной запрос выбирает наилучшее соответствие.

Обратите внимание, что:

  • Поиск основан на текущей дате
  • Мы рассчитываем только разницу в днях, время (часы, минуты и т. Д.) Игнорируется
  • Если два дня равноудалены (скажем, 2 до и 2 после), мы выбираем один случайным образом

Все они могут быть скорректированы с учетом ваших конечных требований.

2 голосов
/ 14 июня 2011

(Филлип превзошел меня, и функции управления окнами - отличный выбор. Вот альтернативный подход:)

Если я правильно понимаю ваше требование как получение даты , ближайшей к текущей дате, будь то в прошлом или в будущем , рассмотрите этот запрос:

SELECT t.Name, t.AppointmentDate
FROM
(
    SELECT Name, AppointmentDate, ABS(DATEDIFF(d, GETDATE(), AppointmentDate)) AS Distance
    FROM Table
) t
JOIN
(
    SELECT Name, MIN(ABS(DATEDIFF(d, GETDATE(), AppointmentDate))) AS MinDistance
    FROM Table
    GROUP BY Name
) d ON t.Name = d.Name AND t.Distance = d.MinDistance
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...