web-dev-qa-db-fra.com

Sélection de la date la plus récente entre deux colonnes

Si j'ai une table qui (entre autres colonnes) a deux colonnes DATETIME, comment pourrais-je sélectionner le le plus récent date dans ces deux colonnes.

Exemple:

ID     Date1     Date2

1      1/1/2008   2/1/2008

2      2/1/2008   1/1/2008

3      1/10/2008  1/10/2008

Si je voulais que mes résultats ressemblent 

ID     MostRecentDate

1      2/1/2008

2      2/1/2008

3      1/10/2008

Existe-t-il un moyen simple de le faire que je néglige évidemment? Je sais que je peux faire des sous-requêtes et des déclarations de cas ou même écrire une fonction dans SQL Server pour le gérer, mais je pensais qu'il existait déjà une fonction de type comparaison maximale que je suis en train de oublier.

21
TheTXI

CASE est à mon humble avis votre meilleure option:

SELECT ID,
       CASE WHEN Date1 > Date2 THEN Date1
            ELSE Date2
       END AS MostRecentDate
FROM Table

Si l'une des colonnes est nullable, il suffit de la mettre dans COALESCE :

.. COALESCE(Date1, '1/1/1973') > COALESCE(Date2, '1/1/1973')
36
Rockcoder
select ID, 
case
when Date1 > Date2 then Date1
else Date2
end as MostRecentDate
from MyTable
5
RedFilter

Vous pouvez le jeter dans une fonction scalaire, ce qui facilite un peu la gestion des valeurs nulles. De toute évidence, cela ne va pas être plus rapide que la déclaration de cas en ligne.

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
5
Michael Haren

Dans la mesure du possible, utilisez les fonctions InLine car elles ne présentent aucun des problèmes de performances généralement associés aux fichiers UDF ...

Create FUNCTION MaximumDate 
(   
@DateTime1 DateTime,
@DateTime2 DateTime
)
RETURNS TABLE 
AS
RETURN 
(
    Select Case When @DateTime1 > @DateTime2 Then @DateTime1
                Else @DateTime2 End MaxDate
)
GO 

Pour des instructions d'utilisation, voir ici

2
Charles Bretana

Je pense que la réponse acceptée est la plus simple. Cependant, je surveillerais les valeurs nulles dans les dates ...

SELECT ID,
       CASE WHEN ISNULL(Date1,'01-01-1753') > ISNULL(Date2,'01-01-1753') THEN Date1
            ELSE Date2
       END AS MostRecentDate
FROM Table
2
JStevens

Autre que la déclaration de cas, je ne crois pas si ... 

  Select Case When DateColA > DateColB Then DateColA 
              Else DateColB End MostRecent
  From Table ... 
1
Charles Bretana

De SQL Server 2012 il est possible d'utiliser le raccourci IIF vers CASE même si cette dernière est SQL Standard:

SELECT ID,
       IIF(DateColA > DateColB, DateColA, DateColB) AS MostRecentDate
  FROM theTable
1
Andre Figueiredo

Ce fil a plusieurs solutions. Si vous aviez plus de 2 dates à comparer, il pourrait être préférable d’utiliser un mot clé non-écrit plutôt que d’écrire une série de déclarations de cas. Ce qui suit a été volé de manière flagrante à Niikola :

select id, max(dDate) MostRecentDate
  from YourTable
    unpivot (dDate for nDate in (Date1, Date2, Date3)) as u
  group by id 

Ensuite, vous pouvez order by dDate, si cela vous aide.

0
Michael

Autant que je sache, il n'y a pas de fonction intégrée pour obtenir le maximum de deux valeurs, mais vous pouvez écrire votre propre facilement comme suit:

CREATE FUNCTION dbo.GetMaximumDate(@date1 DATETIME, @date2 DATETIME)
RETURNS DATETIME
AS
BEGIN
    IF (@date1 > @date2)
        RETURN @date1
    RETURN @date2
END

et appelez comme

SELECT Id, dbo.GetMaximumDate(Date1, Date2)
FROM tableName
0
Recep
select max(d) ChangeDate
from (values(@d), (@d2)) as t(d)
0
syb

Toutes les autres réponses correctes comme déjà posté.

Mais si vous recherchez toujours un mot clé MAX, voici un moyen: 

select ID , MAX(dt) from 
(  select Id , Date1 as dt from table1
   union  
   select ID , Date2 from table2
) d
group by d.Id
0
Dhananjay