鉴于此架构:
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');
如果我在子查询中使用 COALESCE,它会返回 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 |
+----+---------------------+---------------------+
但是,如果它放在子查询之外:
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 |
+----+---------------------+---------------------+
为什么第一个子查询不返回:t1.DateTest
?
只有在 FROM 语句中返回了行时,才会返回 select 中的内容。
首先,让我们从概念上考虑一下。
查询 1 是这样的:
查询将返回没有行 - 因为车库里没有法拉利。(至少,在我自己的车库里没有找到任何行。)
查询 2 不同:
这就是合并必须在搜索操作之外的原因:即使结果集中没有行,您也需要它发生。
现在,让我们看看您的查询。
我将自己取出子查询,并且我将为您希望 COALESCE 工作的行之一硬编码值,但它不能:
在 WHERE 子句中,我硬编码了 Id = 1 和 DateTest > '2017-02-03 00:00:00.000'。当此查询运行时,它不返回任何结果:
这就是 COALESCE 不起作用的原因:此结果集中没有行,您的车库中也没有法拉利。掌握这个概念,你的车里就会有法拉利……等一下……我已经掌握了这个概念,我的车库里没有法拉利……