我很确定这是一个隐式转换,但我无法找到有关它的信息。
假设我有这个 SQL:
SELECT
CASE WHEN (SELECT 1 WHERE (1=1)) = 1 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
我的子查询返回一行,因此与 1 进行比较。这导致我的 CASE WHEN 产生 1 输出。
即使我将子查询设置为不返回如下示例所示的行,CASE 语句也会返回 0 结果:
SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 1 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
使用这种类型的比较让我感到不舒服。以我的拙见,最好像这样使用 EXISTS:
SELECT
CASE WHEN EXISTS(SELECT 1 WHERE (1=1)) THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)如果我不使用 EXISTS 有什么优点或缺点吗?
Tom*_*m V 10
SQL 解释器是否在“空集”到 0 或 1 之间进行转换?
不,查询没有返回 0,因为空结果被认为等于 0,但因为空结果集被考虑,NULL
而 null 不等于任何东西。
正如你发现的
SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 1 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
返回 0
但
SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) = 0 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
也返回 0。
所以空结果集不是 1 也不是 0,它是 NULL,正如
SELECT
CASE WHEN (SELECT 1 WHERE (1=0)) is NULL THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
返回 1。
使用该代码查看此dbfiddle。
NULL
是未知的,所以 SQL Server 不知道它等于什么。
以我的拙见,最好使用 EXISTS
如果你依赖结果集的存在,我同意EXISTS
可能是要走的路。这就是建造的目的。
如果你想比较 2 个值,你需要使用CASE
但对于你陈述的场景,我会使用 EXISTS
如果您的结果集有多于一行或多列,您的比较就会中断。
例如
SELECT
CASE WHEN (SELECT 1,2 WHERE (1=1)) = 1 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
返回
Msg 116 Level 16 State 1 Line 2 当子查询没有用EXISTS引入时,选择列表中只能指定一个表达式。
和
SELECT
CASE WHEN (SELECT 1 WHERE (1=1) UNION SELECT 2 WHERE (1=1)) = 1 THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)
返回
消息 512 级别 16 状态 1 第 1 行子查询返回了 1 个以上的值。当子查询跟随 =、!=、<、<=、>、>= 或当子查询用作表达式时,这是不允许的。
归档时间: |
|
查看次数: |
19799 次 |
最近记录: |