标准SQL是否允许对联合表达式进行分组?

时间:2013-04-10 21:12:02

标签: sql union language-lawyer operator-precedence parentheses

我瞥了一眼SQL-92标准,然后是一个SQL-92语法,有人放在一起但是听不懂。

正如SQL Server documentation提醒我们的那样,有些情况下应该明确地对表达式进行分组:

  

默认情况下,SQL   Server 2005评估包含UNION运算符的语句   左到右。使用括号指定评估顺序。对于   例如,以下陈述不相同:

/* First statement. */
SELECT * FROM TableA
UNION ALL
(   SELECT * FROM TableB
   UNION
   SELECT * FROM TableC
)
GO

/* Second statement. */
(SELECT * FROM TableA
 UNION ALL
 SELECT * FROM TableB
)
UNION
SELECT * FROM TableC)
GO
  

在第一个语句中,重复项在组合之间被删除   表B和表C.在该集和TableA之间的联合中,   重复不会被消除。在第二个声明中,重复是   包括在TableA和TableB之间的联合中,但是被淘汰了   随后与TableC联合。 ALL对决赛没有任何影响   这个表达的结果。

但我发现MySQL和SqlLite不支持它(供参考,Oracle,SQL Server,Postgres和DB2使用。)

那么如何检查规格是否允许?

1 个答案:

答案 0 :(得分:0)

摘自the SQL-92 grammar,摘自SQL-92标准并已超链接:

<direct select statement: multiple rows>    ::=   <query expression> [ <order by clause> ]

<query expression>    ::=   <non-join query expression> | <joined table>

<non-join query expression>    ::= 
         <non-join query term>
     |     <query expression>  UNION  [  ALL  ] [ <corresponding spec> ] <query term>
     |     <query expression>  EXCEPT  [  ALL  ] [ <corresponding spec> ] <query term>

<joined table>    ::= 
         <cross join>
     | <qualified join>
     | <left paren> <joined table> <right paren>

<non-join query term>    ::= 
         <non-join query primary>
     |     <query term>  INTERSECT  [  ALL  ] [ <corresponding spec> ] <query primary>

<query term>    ::=   <non-join query term> | <joined table>

<cross join>    ::= 
         <table reference>  CROSS  JOIN <table reference>

<qualified join>    ::= 
         <table reference> [  NATURAL  ] [ <join type> ]  JOIN <table reference> [ <join specification> ]

<non-join query primary>    ::=   <simple table> | <left paren> <non-join query expression> <right paren>

<query primary>    ::=   <non-join query primary> | <joined table>

<table reference>    ::= 
         <table name> [ <correlation specification> ]
     | <derived table> <correlation specification>
     | <joined table>

<simple table>    ::= 
         <query specification>
     |     <table value constructor>
     |     <explicit table>

<query specification>    ::= 
          SELECT  [ <set quantifier> ] <select list> <table expression>

<table expression>    ::= 
         <from clause>
         [ <where clause> ]
         [ <group by clause> ]
         [ <having clause> ]

&lt;直接选择语句:多行&gt;是我们将匹配的规则。 我们检查

SELECT * FROM p匹配&lt;查询规范&gt;,&lt;简单表格&gt;,&lt;非联接查询主要&gt;,&lt;非联接查询字词&gt;,&lt;非联接查询表达式&gt;,&lt;查询表达式&gt;

SELECT * FROM p UNION SELECT * FROM q匹配&lt;非联接查询表达式&gt;

(SELECT * FROM p UNION SELECT * FROM q)匹配&lt;非联接查询主要&gt;,&lt;非联接查询字词&gt;,&lt;非联接查询表达式&gt;,&lt;查询表达式&gt;

(SELECT * FROM p UNION SELECT * FROM q) UNION SELECT * FROM r现在匹配&lt;非联接查询表达式&gt;和&lt;查询表达式&gt;。

因此它匹配&lt; direct select statement:multiple rows&gt;,所以它是一个有效的SQL-92语句。

类似地,SELECT * FROM p UNION (SELECT * FROM q UNION SELECT * FROM r)(SELECT * FROM p)(SELECT * FROM p UNION SELECT * FROM q)甚至p CROSS JOIN q都是有效的SQL-92选择语句。