【问题标题】:Does standard SQL allow grouping of union expressions?标准 SQL 是否允许对联合表达式进行分组?
【发布时间】:2013-04-02 22:09:54
【问题描述】:

我看了一眼 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 支持。)

那么我如何检查规范是否允许呢?

【问题讨论】:

  • 究竟什么是 MySQL 和 SqlLite 不支持的?
  • 公式如SELECT * FROM p UNION (SELECT * FROM p UNION SELECT * FROM p)

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


【解决方案1】:

摘自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> ]

是我们将要匹配的规则。 我们检查一下

SELECT * FROM p 匹配

SELECT * FROM p UNION SELECT * FROM q 匹配

(SELECT * FROM p UNION SELECT * FROM q) 匹配

(SELECT * FROM p UNION SELECT * FROM q) UNION SELECT * FROM r 现在匹配

因此它匹配,因此它是有效的 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 选择语句。

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多