Выбор самой последней даты между двумя столбцами
Если у меня есть таблица, в которой (среди других столбцов) есть два столбца DATETIME, как бы выбрать самую последнюю дату из этих двух столбцов.
Пример:
ID Date1 Date2
1 1/1/2008 2/1/2008
2 2/1/2008 1/1/2008
3 1/10/2008 1/10/2008
Если бы мне хотелось, чтобы мои результаты выглядели как
ID MostRecentDate
1 2/1/2008
2 2/1/2008
3 1/10/2008
Есть ли простой способ сделать это, что я, очевидно, не замечаю? Я знаю, что могу выполнять подзапросы и case-заявления или даже писать функцию в SQL-сервере, чтобы обрабатывать ее, но у меня было это в голове, что была уже построена функция типа max-compare, о которой я просто забываю.
Ответы
Ответ 1
CASE - ИМХО, ваш лучший вариант:
SELECT ID,
CASE WHEN Date1 > Date2 THEN Date1
ELSE Date2
END AS MostRecentDate
FROM Table
Если один из столбцов является нулевым, просто нужно заключить в COALESCE
:
.. COALESCE(Date1, '1/1/1973') > COALESCE(Date2, '1/1/1973')
Ответ 2
select ID,
case
when Date1 > Date2 then Date1
else Date2
end as MostRecentDate
from MyTable
Ответ 3
Вы можете бросить это в скалярную функцию, которая упрощает обработку нулей. Очевидно, что это не будет быстрее, чем оператор inline case.
ALTER FUNCTION [fnGetMaxDateTime] (
@dtDate1 DATETIME,
@dtDate2 DATETIME
) RETURNS DATETIME AS
BEGIN
DECLARE @dtReturn DATETIME;
-- If either are NULL, then return NULL as cannot be determined.
IF (@dtDate1 IS NULL) OR (@dtDate2 IS NULL)
SET @dtReturn = NULL;
IF (@dtDate1 > @dtDate2)
SET @dtReturn = @dtDate1;
ELSE
SET @dtReturn = @dtDate2;
RETURN @dtReturn;
END
Ответ 4
Я думаю, что принятый ответ является самым простым. Тем не менее, я бы посмотрел на нулевые значения в датах...
SELECT ID,
CASE WHEN ISNULL(Date1,'01-01-1753') > ISNULL(Date2,'01-01-1753') THEN Date1
ELSE Date2
END AS MostRecentDate
FROM Table
Ответ 5
За исключением случая, я так не считаю...
Select Case When DateColA > DateColB Then DateColA
Else DateColB End MostRecent
From Table ...
Ответ 6
По возможности используйте функции InLine, поскольку они не имеют проблем с производительностью, обычно связанных с UDF...
Create FUNCTION MaximumDate
(
@DateTime1 DateTime,
@DateTime2 DateTime
)
RETURNS TABLE
AS
RETURN
(
Select Case When @DateTime1 > @DateTime2 Then @DateTime1
Else @DateTime2 End MaxDate
)
GO
Инструкции по использованию см. Здесь
Ответ 7
От SQL Server 2012 можно использовать ярлык IIF
для выражения CASE
, хотя последний стандарт SQL:
SELECT ID,
IIF(DateColA > DateColB, DateColA, DateColB) AS MostRecentDate
FROM theTable
Ответ 8
AFAIK, нет встроенной функции для получения максимум двух значений, но вы можете написать свой собственный легко, как:
CREATE FUNCTION dbo.GetMaximumDate(@date1 DATETIME, @date2 DATETIME)
RETURNS DATETIME
AS
BEGIN
IF (@date1 > @date2)
RETURN @date1
RETURN @date2
END
и назовите его
SELECT Id, dbo.GetMaximumDate(Date1, Date2)
FROM tableName
Ответ 9
Этот поток имеет несколько решений. Если у вас было более двух дат для сравнения, "непривитие" могло бы быть предпочтительным для написания ряда утверждений о случаях. Следующее явно украдено из Niikola:
select id, max(dDate) MostRecentDate
from YourTable
unpivot (dDate for nDate in (Date1, Date2, Date3)) as u
group by id
Тогда вы можете order by dDate
, если это полезно.
Ответ 10
Все другие правильные ответы, уже опубликованные.
Но если вы все еще ищете ключевое слово MAX, то вот путь:
select ID , MAX(dt) from
( select Id , Date1 as dt from table1
union
select ID , Date2 from table2
) d
group by d.Id
Ответ 11
select max(d) ChangeDate
from (values(@d), (@d2)) as t(d)
Ответ 12
Почему вы не могли использовать функцию GREATEST?
select id, date1, date2, GREATEST( nvl(date1,date2) , nvl(date2, date1) )
from table1;
Я включил NVL, чтобы гарантировать, что NULL был оценен правильно, иначе, если Date1 или Date2 имеет значение null, Greatest возвращает NULL.
ID Date1 Date2 MostRecentDate
1 1/1/2008 2/1/2008 2/1/2008
2 2/1/2008 1/1/2008 2/1/2008
3 1/10/2008 1/10/2008 1/10/2008
4 -null- 2/10/2008 2/10/2008
5 2/10/2008 -null- 2/10/2008