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, ela 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
?
As coisas no select são retornadas apenas se houver linhas retornadas na instrução FROM.
Primeiro, vamos pensar nisso conceitualmente.
A consulta 1 é assim:
A consulta voltava sem filas - porque não havia uma Ferrari na garagem. (Pelo menos, não havia nenhuma fila encontrada 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 ela aconteça mesmo quando não houver linhas no conjunto de resultados.
Agora, vamos analisar 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 esta consulta é executada, ela não retorna resultados:
É por isso que o COALESCE não funciona: não havia filas neste conjunto de resultados e nenhuma Ferrari na sua garagem. Domine esse conceito, e você terá Ferraris na sua... espere um minuto... eu dominei esse conceito, e não há Ferraris na minha garagem...