Compte tenu de ce schéma:
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 j'utilise COALESCE dans une sous-requête, elle renvoie 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 |
+----+---------------------+---------------------+
Cependant, s'il est placé en dehors de la sous-requête:
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 |
+----+---------------------+---------------------+
Pourquoi le premier sous - requête ne retourne pas: t1.DateTest
?
sql-server
McNets
la source
la source
Réponses:
Les éléments de la sélection ne sont renvoyés que si des lignes sont renvoyées dans l'instruction FROM.
Tout d'abord, réfléchissons conceptuellement.
La requête 1 est comme:
La requête reviendrait sans lignes - car il n'y avait pas de Ferrari dans le garage. (Au moins, aucune rangée n'a été trouvée dans mon propre garage.)
La requête 2 est différente:
C'est pourquoi la fusion doit être en dehors de l'opération de recherche: vous en avez besoin même s'il n'y a pas de lignes dans le jeu de résultats.
Examinons maintenant votre requête.
Je vais supprimer la sous-requête seule et je vais coder en dur les valeurs pour l'une des lignes où vous voulez que COALESCE fonctionne, mais cela ne peut pas:
Dans la clause WHERE, j'ai codé en dur Id = 1 et DateTest> '2017-02-03 00: 00: 00.000'. Lorsque cette requête s'exécute, elle ne renvoie aucun résultat:
C'est pourquoi le COALESCE ne fonctionne pas: il n'y avait pas de rangées dans cet ensemble de résultats et pas de Ferrari dans votre garage. Maîtrisez ce concept, et vous aurez des Ferrari dans votre ... attendez une minute ... J'ai maîtrisé ce concept, et il n'y a pas de Ferrari dans mon garage ...
la source