可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
If I have a table that (among other columns) has two DATETIME columns, how would I select the most recent date from those two columns.
Example:
ID Date1 Date2
1 1/1/2008 2/1/2008
2 2/1/2008 1/1/2008
3 1/10/2008 1/10/2008
If I wanted my results to look like
ID MostRecentDate
1 2/1/2008
2 2/1/2008
3 1/10/2008
Is there a simple way of doing this that I am obviously overlooking? I know I can do subqueries and case statements or even write a function in sql server to handle it, but I had it in my head that there was a max-compare type function already built in that I am just forgetting about.
回答1:
CASE is IMHO your best option:
SELECT ID,
CASE WHEN Date1 > Date2 THEN Date1
ELSE Date2
END AS MostRecentDate
FROM Table
If one of the columns is nullable just need to enclose in 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:
You can throw this into a scalar function, which makes handling nulls a little easier. Obviously it isn't going to be any faster than the inline case statement.
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:
I think the accepted answer is the simplest. However, I would watch for null values in the dates...
SELECT ID,
CASE WHEN ISNULL(Date1,'01-01-1753') > ISNULL(Date2,'01-01-1753') THEN Date1
ELSE Date2
END AS MostRecentDate
FROM Table
回答5:
From SQL Server 2012 it's possible to use the shortcut IIF
to CASE
expression though the latter is SQL Standard:
SELECT ID,
IIF(DateColA > DateColB, DateColA, DateColB) AS MostRecentDate
FROM theTable
回答6:
Whenever possible, use InLine functions as they suffer none of the performance issues generally associated with UDFs...
Create FUNCTION MaximumDate
(
@DateTime1 DateTime,
@DateTime2 DateTime
)
RETURNS TABLE
AS
RETURN
(
Select Case When @DateTime1 > @DateTime2 Then @DateTime1
Else @DateTime2 End MaxDate
)
GO
For usage guidelines, see Here
回答7:
Other than case statement, I don't believe so...
Select Case When DateColA > DateColB Then DateColA
Else DateColB End MostRecent
From Table ...
回答8:
AFAIK, there is no built-in function to get the maximum of two values, but you can write your own easily as:
CREATE FUNCTION dbo.GetMaximumDate(@date1 DATETIME, @date2 DATETIME)
RETURNS DATETIME
AS
BEGIN
IF (@date1 > @date2)
RETURN @date1
RETURN @date2
END
and call it as
SELECT Id, dbo.GetMaximumDate(Date1, Date2)
FROM tableName
回答9:
This thread has several solutions. If you had more than 2 dates to compare, "unpivot" might be preferable to writing a series of case statements. The following is blatantly stolen from Niikola:
select id, max(dDate) MostRecentDate
from YourTable
unpivot (dDate for nDate in (Date1, Date2, Date3)) as u
group by id
Then you can order by dDate
, if that's helpful.
回答10:
All other correct answers as already posted.
But if you are still really looking for MAX keyword then here is a way :
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:
select ID,(select max(d) from (select Date1 d uninon select Date2 d) as t) as MaxDate
from MyTable
回答13:
Why couldn't you use the GREATEST function?
select id, date1, date2, GREATEST( nvl(date1,date2) , nvl(date2, date1) )
from table1;
I included a NVL to ensure that NULL was evaluated correctly, otherwise if either Date1 or Date2 is null, the Greatest returns 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