You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何UNION操作数必须是SELECT语句而非表或视图?

为什么SQL中UNION的操作数必须是SELECT语句?

先看具体场景:
我们有两个结构相同的表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'。

另外,把SELECT * FROM "S"和SELECT * FROM "T"分别创建为视图view1、view2后,执行"view1" UNION "view2"同样报错:SQLite提示near "UNION": syntax error,SQL Server提示Incorrect syntax near 'view1'。

从关系代数定义来看,UNION运算符确实是以两个关系(表)为操作数输出新关系,基表、派生关系都属于关系范畴,但SQL的处理却不一样,原因如下:

  • SQL语法规范的硬性要求:SQL语言的语法规则明确规定,UNION这类集合运算符的操作数必须是查询表达式(Query Expression),而直接的表名或视图名并不属于查询表达式的直接写法。查询表达式的核心就是SELECT语句,哪怕是最简单的SELECT * FROM 表名,这是SQL语法解析器的强制要求,不符合这个格式的语句会直接被判定为语法错误。

  • 关系代数与SQL实现的差异:C.J.Date的理论中,关系是抽象的概念,但SQL是一门实际的编程语言,需要明确的语法结构来让解析器识别操作逻辑。直接写表名无法让解析器明确你要对这个表执行什么操作——虽然默认是取全部数据,但SQL没有把“直接写表名”等价于“SELECT * FROM 表名”作为集合运算的合法输入,必须显式通过SELECT语句来表达“获取该表所有数据”这个操作。

  • 视图的本质是封装的查询:视图本身并不是一个物理存储的表(除非是物化视图),它本质是一段预定义的SELECT语句。引用视图的时候,SQL需要把视图展开为对应的SELECT语句才能执行,但在集合运算中,你不能直接把视图名当作操作数,必须通过SELECT * FROM view1这样的形式,将其转化为合法的查询表达式,才能参与UNION运算。

内容的提问来源于stack exchange,提问作者Ardy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:12:39