SQL联合ALL和Except

Sar*_*rah 1 sql union sql-except

我在SQL中执行except和union语句时看到一种奇怪的行为。

我有两张桌子

Select * from #old
Run Code Online (Sandbox Code Playgroud)

数据看起来像这样

oid1    oid2    co
   1      11     1
   2      22     1
   3      33     1
   4      55     1

Select * from #new

nid1    nid2    co
   1      11     3
   2      22     1
   3      33     1
   4      44     1
   4      55     1
Run Code Online (Sandbox Code Playgroud)

这是我最后的查询

Select * from #old
    except
    Select * from #new
    union all
    Select * from #new
    except
    Select * from #old
Run Code Online (Sandbox Code Playgroud)

并提供这些记录

oid1    oid2    co
   1      11     3
   4      44     1
Run Code Online (Sandbox Code Playgroud)

我的问题是..不应该在第一个except子句的另一行中:

Select * from #old
except
Select * from #new
Run Code Online (Sandbox Code Playgroud)

这是

oid1    oid2    co    
   1      11     1
Run Code Online (Sandbox Code Playgroud)

最终查询不应具有3行而不是只有2行,因为并非所有列都相同。

Gor*_*off 6

您似乎认为查询被解释为:

(Select * from #old
 except
 Select * from #new
)
union all
(Select * from #new
 except
 Select * from #old
)
Run Code Online (Sandbox Code Playgroud)

但不是。它被解释为:

((Select * from #old
  except
  Select * from #new
 )
 union all
 Select * from #new
)
except
Select * from #old
Run Code Online (Sandbox Code Playgroud)

这等效于:

Select * from #new
except
Select * from #old
Run Code Online (Sandbox Code Playgroud)

这是查询返回的内容。

文档中对此进行了解释:

如果在表达式中将EXCEPT或INTERSECT与其他运算符一起使用,则会在以下优先级的上下文中对其进行评估:

  1. 括号中的表达式

  2. INTERSECT运算符

  3. EXCEPT和UNION根据它们在表达式中的位置从左到右求值

  • 完美,非常感谢。是的,这正是我在解释它,今天学到了一些新东西。不知道那些运营商规则。谢谢!! (2认同)