¿Cómo puedo incluir valores nulos en un MIN o MAX?
Tengo una tabla donde estoy almacenando datos de intervalos de tiempo. la tabla tiene un esquema similar a:
ID INT NOT NULL IDENTITY(1,1)
RecordID INT NOT NULL
StartDate DATE NOT NULL
EndDate DATE NULL
Y estoy tratando de calcular las fechas de inicio y finalización para cada id de registro, por lo que la fecha de inicio mínima y la fecha de finalización máxima. startDate no es nullable, así que no tengo que preocuparme por esto, pero necesito el MAX(endDate) para indicar que esto es actualmente un intervalo de tiempo en ejecución.
Es importante que mantenga el valor NULL de endDate y lo trate como el valor máximo.
El el intento más simple (abajo) no funciona resaltando el problema de que MIN y MAX ignorarán los NULLS (fuente: http://technet.microsoft.com/en-us/library/ms179916.aspx).
SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid
He creado un violín SQL con la configuración básica hecha.
Http://sqlfiddle.com/#! 3 / b0a75
¿Cómo puedo doblar SQL Server 2008 a mi voluntad para producir el siguiente resultado a partir de los datos dados en el SQLFiddle?
RecordId Start End
1 2009-06-19 NULL
2 2012-05-06 NULL
3 2013-01-25 NULL
4 2004-05-06 2009-12-01
7 answers
Es un poco feo, pero debido a que las NULL
s tienen un significado especial para ti, esta es la forma más limpia que se me ocurre para hacerlo:
SELECT recordid, MIN(startdate),
CASE WHEN MAX(CASE WHEN enddate IS NULL THEN 1 ELSE 0 END) = 0
THEN MAX(enddate)
END
FROM tmp GROUP BY recordid
Es decir, si cualquier fila tiene un NULL
, queremos forzar que sea la respuesta. Solo si ninguna fila contiene un NULL
debemos devolver el MIN
(o MAX
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-22 15:15:06
El efecto que desea es tratar el NULL como la fecha más grande posible y luego reemplazarlo con NULL nuevamente al completarlo:
SELECT RecordId, MIN(StartDate), NULLIF(MAX(COALESCE(EndDate,'9999-12-31')),'9999-12-31')
FROM tmp GROUP BY RecordId
Por su violín esto devolverá los resultados exactos que especifique bajo todas las condiciones.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-27 03:50:04
En mi expresión - count (enddate) cuenta cuántas filas donde enddates no son null contar(*) contar cuántas filas totales Al comparar, puede saber fácilmente si alguna fecha final contiene null. Si son idénticos entonces max(enddate) es el resultado. De lo contrario, el caso devolverá null por defecto, que también es la respuesta. Esta es una forma muy popular de hacer esta verificación exacta.
SELECT recordid,
MIN(startdate),
case when count(enddate) = count(*) then max(enddate) end
FROM tmp
GROUP BY recordid
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-23 09:57:19
Use IsNull
SELECT recordid, MIN(startdate), MAX(IsNull(enddate, Getdate()))
FROM tmp
GROUP BY recordid
He modificado MIN en la segunda instrucción a MAX
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-22 14:58:32
Suponiendo que solo tiene un registro con null en la columna endDate para un registro dado, algo como esto debería darte la salida deseada:
WITH cte1 AS
(
SELECT recordid, MIN(startdate) as min_start , MAX(enddate) as max_end
FROM tmp
GROUP BY recordid
)
SELECT a.recordid, a.min_start ,
CASE
WHEN b.recordid IS NULL THEN a.max_end
END as max_end
FROM cte1 a
LEFT JOIN tmp b ON (b.recordid = a.recordid AND b.enddate IS NULL)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-22 15:23:26
Utilice la función analítica:
select case when
max(field) keep (dense_rank first order by datfin desc nulls first) is null then 1
else 0 end as flag
from MYTABLE;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-22 12:09:05
Trato de usar una unión para combinar dos consultas para formatear los retornos que desea:
SELECT recordid, startdate, enddate FROM tmp
Where enddate is null
UNION
SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid
Pero no tengo idea si el Sindicato tendría un gran impacto en el rendimiento
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 14:01:59