Biorąc pod uwagę ten schemat:
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');
Jeśli użyję COALESCE w podzapytaniu, zwraca 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 |
+----+---------------------+---------------------+
Jeśli jednak zostanie umieszczony poza podzapytaniem:
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 |
+----+---------------------+---------------------+
Dlaczego pierwszy podzapytanie nie wraca: t1.DateTest
?
sql-server
McNets
źródło
źródło
Odpowiedzi:
Rzeczy w zaznaczeniu są zwracane tylko wtedy, gdy w instrukcji FROM zwracane są wiersze.
Po pierwsze, pomyślmy o tym koncepcyjnie.
Zapytanie 1 jest jak:
Zapytanie wróci bez żadnych wierszy - ponieważ w garażu nie było Ferrari. (Przynajmniej w moim garażu nie znaleziono żadnych wierszy).
Zapytanie 2 jest inne:
Dlatego koalescencja musi znajdować się poza operacją wyszukiwania: musisz to zrobić, nawet jeśli w zestawie wyników nie ma wierszy.
Teraz spójrzmy na twoje zapytanie.
Wybiorę podzapytanie na własną rękę i idę do twardego kodu wartości dla jednego z wierszy, w których chcesz, aby działał COALESCE, ale nie może:
W klauzuli WHERE mam zakodowane na stałe Id = 1 i DateTest> '2017-02-03 00: 00: 00.000'. Po uruchomieniu tego zapytania nie zwraca żadnych wyników:
Właśnie dlatego COALESCE nie działa: w tym zestawie wyników nie było wierszy i nie ma Ferrari w garażu. Opanuj tę koncepcję, a będziesz mieć Ferrarisa w swoim ... poczekaj chwilę ... Opanowałem tę koncepcję, aw moim garażu nie ma Ferrarisa ...
źródło