为什么 UNION 的操作数应该是 SELECT 语句而不是表?

问题描述 投票:0回答:1

在 SQL 中,给定具有相同架构的表

T
S
,例如,

CREATE TABLE "T" ("ID" INTEGER, "Salary" REAL);
CREATE TABLE "S" ("ID" INTEGER, "Salary" REAL);

我们可以通过命令合并这两种关系

(SELECT * FROM "S") UNION (SELECT * FROM "T");

但是以下命令给出了错误:

"S" UNION "T";

SQLite 中的错误消息:

near "UNION": syntax error

SQL Server 中的错误消息:

Incorrect syntax near the keyword 'UNION'.

为什么我们不能使用后一个命令?从代数上来说,联合运算符被定义为采用两个表操作数并输出另一个表作为结果。所以

"S" UNION "T"
必须起作用。这类似于选择和投影运算符如何获取表操作数并输出另一个表。

我知道,虽然

SELECT
语句的输出在代数上应该是一个表,但实际上它是一个“虚拟表”。我对 C. J. Date 的《数据库系统简介(第 8 版)》的理解是,像上面的 S
T
这样的表是“基本关系/关系”,而像
(SELECT * FROM "S")
(SELECT * FROM "T")
这样的虚拟表是“派生关系” ”;并且两者(基础和派生)都被视为表。那么当
UNION
对它们进行操作时,为什么它们的行为不一样呢?
有趣的是,在我们分别为 

view1

view2
的输出命名
(SELECT * FROM "S")
(SELECT * FROM "T")
来创建视图后,
CREATE VIEW "view1" AS SELECT * FROM "S";
CREATE VIEW "view2" AS SELECT * FROM "T";

如果我们将视图作为操作数提供给 
UNION

,我们将再次收到错误:

"view1" UNION "view2";

SQLite 中的错误消息:
near "UNION": syntax error

SQL Server 中的错误消息:

Incorrect syntax near 'view1'.

发生什么事了?为什么操作数必须是 

SELECT

语句?

    

sql sqlite relational-database rdbms relational-algebra
1个回答
0
投票
声明兼容性

,某些功能是可选的)。 无论如何,

SQL 标准

按照您期望的方式定义了 UNION 运算符: <non-join query expression> ::= <non-join query term> | <query expression> UNION [ ALL ] [ <corresponding spec> ] <query term>

如果我们展开一切:

    <query term>
  • ::=
    <non-join query term>
  • <non-join query term>
  • ::=
    <non-join query primary>
  • <non-join query primary>
  • ::=
    <simple table>
  • <simple table>
  • ::=
    <explicit table>
  • <explicit table>
  • ::=
    TABLE <table name>
    
    
<explicit table>

TABLE <table name>
相当于
<query expression>
( SELECT * FROM <table name> )

因此,根据标准,您应该能够使用如下语法:

TABLE T UNION TABLE S

但是 SQL 语言的实际实现取决于 RDBMS 开发人员,我不知道有任何支持这样的显式表语句,顺便说一句,对于 

UNION JOIN

也是如此,所以回答你的问题 Why should the operands for UNION be SELECT statements and not tables? - 因为开发人员决定不这样做遵循标准。

    

© www.soinside.com 2019 - 2024. All rights reserved.