Dado este esquema:
CREATE TABLE #TEST_COALESCE
(
Id int NOT NULL,
DateTest datetime NOT NULL,
PRIMARY KEY (Id, DateTest)
);
INSERT INTO #TEST_COALESCE VALUES
(1, '20170201'),
(1, '20170202'),
(1, '20170203'),
(2, '20170204'),
(2, '20170205'),
(2, '20170206');
Se eu usar COALESCE dentro de uma subconsulta, ele retornará NULL.
SELECT t1.Id, t1.DateTest,
(SELECT TOP 1 COALESCE(t2.DateTest, t1.DateTest)
FROM #TEST_COALESCE t2
WHERE t2.Id = t1.Id
AND t2.DateTest > t1.DateTest
ORDER BY t2.Id, t2.DateTest) NextDate
FROM #TEST_COALESCE t1;
+----+---------------------+---------------------+
| Id | DateTest | NextDate |
+----+---------------------+---------------------+
| 1 | 01.02.2017 00:00:00 | 02.02.2017 00:00:00 |
| 1 | 02.02.2017 00:00:00 | 03.02.2017 00:00:00 |
| 1 | 03.02.2017 00:00:00 | NULL |
| 2 | 04.02.2017 00:00:00 | 05.02.2017 00:00:00 |
| 2 | 05.02.2017 00:00:00 | 06.02.2017 00:00:00 |
| 2 | 06.02.2017 00:00:00 | NULL |
+----+---------------------+---------------------+
No entanto, se for colocado fora da subconsulta:
SELECT t1.Id, t1.DateTest,
COALESCE((SELECT TOP 1 t2.DateTest
FROM #TEST_COALESCE t2
WHERE t2.Id = t1.Id
AND t2.DateTest > t1.DateTest
ORDER BY t2.Id, t2.DateTest), t1.DateTest) NextDate
FROM #TEST_COALESCE t1;
+----+---------------------+---------------------+
| Id | DateTest | NextDate |
+----+---------------------+---------------------+
| 1 | 01.02.2017 00:00:00 | 02.02.2017 00:00:00 |
| 1 | 02.02.2017 00:00:00 | 03.02.2017 00:00:00 |
| 1 | 03.02.2017 00:00:00 | 03.02.2017 00:00:00 |
| 2 | 04.02.2017 00:00:00 | 05.02.2017 00:00:00 |
| 2 | 05.02.2017 00:00:00 | 06.02.2017 00:00:00 |
| 2 | 06.02.2017 00:00:00 | 06.02.2017 00:00:00 |
+----+---------------------+---------------------+
Por que a primeira subconsulta não retorna t1.DateTest
:?
sql-server
McNets
fonte
fonte
Respostas:
As coisas na seleção são retornadas apenas se houver linhas retornadas na instrução FROM.
Primeiro, vamos pensar conceitualmente.
A consulta 1 é como:
A consulta voltava sem linhas - porque não havia uma Ferrari na garagem. (Pelo menos, não foram encontradas linhas na minha própria garagem.)
A consulta 2 é diferente:
É por isso que a coalescência precisa estar fora da operação de pesquisa: você precisa que aconteça mesmo quando não houver linhas no conjunto de resultados.
Agora, vejamos sua consulta.
Vou remover a subconsulta por conta própria e codificar valores para uma das linhas em que você deseja que o COALESCE funcione, mas não pode:
Na cláusula WHERE, codifiquei Id = 1 e DateTest> '2017-02-03 00: 00: 00.000'. Quando essa consulta é executada, ela não retorna resultados:
É por isso que o COALESCE não funciona: não havia linhas neste conjunto de resultados e nenhum Ferraris em sua garagem. Domine esse conceito, e você terá Ferraris no seu ... espere um minuto ... Eu dominei esse conceito, e não há Ferraris na minha garagem ...
fonte