2009-01-05 23 views
19

Si tengo una tabla que (entre otras columnas) tiene dos columnas DATETIME, ¿cómo seleccionaría la más reciente fecha de esas dos columnas.Seleccionar la fecha más reciente entre dos columnas

Ejemplo:

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 quería que mis resultados para parecerse

ID  MostRecentDate 

1  2/1/2008 

2  2/1/2008 

3  1/10/2008 

¿Hay una manera sencilla de hacer esto que estoy, obviamente, pasando por alto? Sé que puedo hacer subconsultas y declaraciones de casos o incluso escribir una función en el servidor sql para manejarlo, pero tenía en mi cabeza que había una función de tipo de comparación máxima ya incorporada de la que me olvido.

Respuesta

30

CASE es mi humilde opinión la mejor opción:

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

Si una de las columnas es anulable sólo tiene que encerrar en COALESCE:

.. COALESCE(Date1, '1/1/1973') > COALESCE(Date2, '1/1/1973') 
+2

Me imaginé que ese era el caso. Estaba casi seguro de que había una función de comparación de fechas ya construida donde podría haber dicho "seleccionar ID, máximo (fecha1, fecha2)". – TheTXI

+0

no funcionará si una de esas fechas es nula. – ulkas

1

Aparte de instrucción case, I don' t lo creo tan ...

Select Case When DateColA > DateColB Then DateColA 
       Else DateColB End MostRecent 
    From Table ... 
5
select ID, 
case 
when Date1 > Date2 then Date1 
else Date2 
end as MostRecentDate 
from MyTable 
+0

parece que tenemos un consenso :) – RedFilter

+1

Verdad :) El arma más rápida en el oeste era la mía en este caso, lol – Rockcoder

5

Puede incluir esto en una función escalar, lo que simplifica el manejo de los valores nulos. Obviamente, no va a ser más rápido que el enunciado de caso en línea.

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 
1

Siempre que sea posible, las funciones de uso InLine ya que sufren ninguno de los problemas de rendimiento asociados generalmente con UDF ...

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

Para pautas de uso, ver Here

+0

¡Un gran consejo, gracias! – Constantin

0

yo sepa, no hay función incorporada para obtener el máximo de dos valores, pero puede escribir uno fácilmente como:

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

y llamarlo como

SELECT Id, dbo.GetMaximumDate(Date1, Date2) 
FROM tableName 
+0

Eso es realmente lo que iba a terminar haciendo para uso futuro. Estoy usando el método de caso en este problema particular debido a su simplicidad, pero la función de fecha máxima es algo que debería haber tenido – TheTXI

0

This thread tiene varias soluciones. Si tenía más de 2 fechas para comparar, "unpivot" podría ser preferible a escribir una serie de declaraciones de casos. El siguiente es robado descaradamente de Niikola:

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

A continuación, puede order by dDate, si eso es útil.

+0

se ve de alguna manera diff ... necesito probar esto. Gracias. – Dhananjay

0

Todas las demás respuestas correctas ya publicadas.

Pero si usted todavía está realmente en busca de palabras clave MAX entonces aquí es una manera:

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

¿Por qué no se utiliza la función más importante?

select id, date1, date2, GREATEST(nvl(date1,date2) , nvl(date2, date1)) 
from table1; 

I incluyó un NVL para asegurar que NULL se evaluó correctamente, de lo contrario si cualquiera Fecha1 o Date2 es nulo, el mayor devuelve 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 
+1

La pregunta es sobre SQL-Server no Oracle. – bummi

2

Creo que la respuesta aceptada es la más simple. Sin embargo, me gustaría ver a los valores nulos en las fechas ...

SELECT ID, 
     CASE WHEN ISNULL(Date1,'01-01-1753') > ISNULL(Date2,'01-01-1753') THEN Date1 
      ELSE Date2 
     END AS MostRecentDate 
FROM Table 
0
select max(d) ChangeDate 
from (values(@d), (@d2)) as t(d) 
1

De SQL Server 2012 que es posible utilizar el acceso directo a IIFCASE expresión aunque este último es SQL estándar:

SELECT ID, 
     IIF(DateColA > DateColB, DateColA, DateColB) AS MostRecentDate 
    FROM theTable 
Cuestiones relacionadas