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');
Si uso COALESCE dentro de una subconsulta, devuelve 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 |
+----+---------------------+---------------------+
Sin embargo, si se coloca fuera de la 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 qué la primera subconsulta no regresa t1.DateTest
:?
sql-server
McNets
fuente
fuente
Respuestas:
Las cosas en la selección se devuelven solo si hay filas devueltas en la instrucción FROM.
Primero, pensemos en esto conceptualmente.
La consulta 1 es como:
La consulta volvería sin filas, porque no había un Ferrari en el garaje. (Al menos, no se encontraron filas en mi propio garaje).
La consulta 2 es diferente:
Es por eso que la fusión debe estar fuera de la operación de búsqueda: necesita que suceda incluso cuando no haya filas en el conjunto de resultados.
Ahora, veamos su consulta.
Voy a sacar la subconsulta por su cuenta, y voy a codificar valores para una de las filas donde desea que funcione COALESCE, pero no puede:
En la cláusula WHERE, he codificado Id = 1 y DateTest> '2017-02-03 00: 00: 00.000'. Cuando se ejecuta esta consulta, no devuelve resultados:
Es por eso que COALESCE no funciona: no había filas en este conjunto de resultados, ni Ferraris en su garaje. Domina ese concepto, y tendrás Ferraris en tu ... espera un minuto ... He dominado ese concepto, y no hay Ferraris en mi garaje ...
fuente