Подтвердить что ты не робот

Как включить нулевые значения в MIN или MAX?

У меня есть таблица, где хранятся временные данные. таблица имеет схему, похожую на:

ID INT NOT NULL IDENTITY(1,1)   
RecordID INT NOT NULL  
StartDate DATE NOT NULL  
EndDate DATE NULL  

И я пытаюсь определить даты начала и окончания каждого идентификатора записи, поэтому минимальный StartDate и максимальный EndDate. StartDate не имеет значения NULL, поэтому мне не нужно беспокоиться об этом, но мне нужен MAX (EndDate), чтобы обозначить, что в настоящее время это работает.

Важно, чтобы я сохранял значение NULL для EndDate и рассматривал его как максимальное значение.

Самая простая попытка (ниже) не работает, подчеркивая проблему, что MIN и MAX будут игнорировать NULLS (источник: http://technet.microsoft.com/en-us/library/ms179916.aspx).

SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid

Я создал скрипт SQL с базовой настройкой.

http://sqlfiddle.com/#!3/b0a75

Как я могу свести SQL Server 2008 к моей воле, чтобы получить следующий результат из данных, приведенных в 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
4b9b3361

Ответ 1

Это немного уродливо, но поскольку NULL имеет для вас особый смысл, это самый чистый способ, который я могу сделать для этого:

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

То есть, если какая-либо строка имеет NULL, мы хотим заставить это быть ответом. Если строки не содержат NULL, мы должны вернуть MIN (или MAX).

Ответ 2

Эффект, который вы хотите, - это обработать NULL как самую большую возможную дату, а затем заменить его NULL по завершении:

SELECT RecordId, MIN(StartDate), NULLIF(MAX(COALESCE(EndDate,'9999-12-31')),'9999-12-31') 
  FROM tmp GROUP BY RecordId

В вашей игре это вернет точные результаты, которые вы укажете при любых условиях.

Ответ 3

в моем выражении - count (enddate) подсчитывает, сколько строк, где enddates не равно нулю count (*) подсчет количества строк Сравнивая, вы можете легко определить, содержит ли какие-либо enddates значение null. Если они идентичны, то результатом является max (enddate). В противном случае случай будет по умолчанию возвращать null, что также является ответом. Это очень популярный способ сделать эту точную проверку.

SELECT recordid, 
MIN(startdate), 
case when count(enddate) = count(*) then max(enddate) end
FROM tmp 
GROUP BY recordid

Ответ 4

Использовать IsNull

SELECT recordid, MIN(startdate), MAX(IsNull(enddate, Getdate()))
FROM tmp 
GROUP BY recordid

Я изменил MIN во второй инструкции на MAX

Ответ 5

Предполагая, что у вас есть только одна запись с нулевым значением в столбце EndDate для данного RecordID, что-то вроде этого должно дать вам желаемый результат:

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)

Ответ 6

Используйте аналитическую функцию:

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;

Ответ 7

Я пытаюсь использовать объединение для объединения двух запросов для форматирования желаемых результатов:

SELECT recordid, startdate, enddate FROM tmp Where enddate is null UNION SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid

Но я понятия не имею, повлияет ли Союз на производительность