如果语句包含 UNION、INTERSECT 或 EXCEPT 运算符(变体),则 ORDER BY 项必须出现在选择列表中

2024-01-06

我已经阅读了我能找到的与此错误相关的所有问题,但它们并没有完全描述这种情况。在其他情况下,人们正在做一些事情,例如按顺序仅引用一个别名表(从联合的一侧) - 我理解为什么 SQLS 在我读过的所有其他问题中抱怨这个特定的错误。

我不明白为什么 SQL Server 对此有疑问order by; order by 中提到的唯一列肯定是结果集 select 的成员:

--example data:
-- a,b,c
-- 1, ,2
--  ,3,5

SELECT    1 AS a, null AS b, 2 AS c INTO #tmp
UNION
SELECT null AS a,    3 AS b, 5 AS c 

--let's call it a lame version of a rollup
SELECT * FROM #tmp            --detail rows
UNION ALL
SELECT a, b, SUM(c) FROM #tmp --summary row
GROUP BY a, b

--the problem
ORDER BY COALESCE(a, b);

DROP TABLE #tmp;

结果集包含列a and b,我看不出有任何歧义。即使对所有内容(以不同方式)使用别名也无济于事:

SELECT t.a AS z, t.b AS y, t.c FROM #tmp t
UNION ALL
SELECT u.a AS z, u.b AS y, SUM(c) AS c FROM #tmp u
GROUP BY u.a, u.b
ORDER BY COALESCE(z, y);

事实上,奇怪的是,SQL Server 似乎抱怨得更多:

Msg 207, Level 16, State 1, Line 6
Invalid column name 'z'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'z'.           --why complain twice?
Msg 207, Level 16, State 1, Line 6
Invalid column name 'y'.
Msg 104, Level 16, State 1, Line 6
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.

唯一有效的是将其包装为另一个选择:

SELECT * FROM(
  SELECT * FROM #tmp
  UNION ALL
  SELECT a, b, SUM(c) AS c FROM #tmp
  GROUP BY u.a, u.b
) a
ORDER BY COALESCE(a, b);

SELECT * FROM(
  SELECT t.a AS z, t.b AS y, t.c FROM #tmp t
  UNION ALL
  SELECT u.a AS z, u.b AS y, SUM(c) AS c FROM #tmp u
  GROUP BY u.a, u.b
) z
ORDER BY COALESCE(z, y);

这就是我的想法,从概念上讲,SQL Server 在处理结果集之前对其结果集进行了处理order by无论如何..那么什么给呢?


根据HoneyBadger的注释,似乎人们实际上必须只在错误消息的表面值上采用SQLS,而不是假设它从联合查询构建结果集,并使用前导选择中给定列的名称作为别名,然后进行排序..

This...

SELECT a, b, COALESCE(a,b) FROM t
UNION ALL
SELECT a, b, COALESCE(a,b) FROM u
ORDER BY COALESCE(a,b)

...有效,大概是因为它直接指定COALESCE(a,b)在选择列表以及 ORDER BY 中

This...

SELECT * FROM(
  SELECT a, b FROM t
  UNION ALL
  SELECT a, b FROM u
)z
ORDER BY COALESCE(a,b)

...有效,大概是因为正在排序的查询不包含 UNION

使用非工作形式的其他数据库的有趣结果组合:

Oracle:

ORA-01785: ORDER BY 项必须是 SELECT 列表表达式的编号

邮政格雷斯:

错误:无效的 UNION/INTERSECT/EXCEPT ORDER BY 子句详细信息:只能使用结果列名称,不能使用表达式或函数。提示:将表达式/函数添加到每个 SELECT 中,或将 UNION 移至 FROM 子句中

MySQL:

(works)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果语句包含 UNION、INTERSECT 或 EXCEPT 运算符(变体),则 ORDER BY 项必须出现在选择列表中 的相关文章

  • 普通表还是全局临时表?

    我和另一位开发人员正在讨论哪种类型的表更适合我们的任务 它基本上是一个我们将在一天结束时截断的缓存 就我个人而言 我认为没有任何理由为此使用除普通表之外的任何内容 但他想使用全局临时表 其中之一有什么优点吗 使用普通表tempdb如果这只是
  • 在 PL/SQL 中将绑定变量与动态 SELECT INTO 子句结合使用

    我有一个关于 PL SQL 中的动态 SQL 语句中可以使用绑定变量的问题 例如 我知道这是有效的 CREATE OR REPLACE FUNCTION get num of employees p loc VARCHAR2 p job V
  • 在单个 select 语句中多次有条件地求和同一列?

    我有一个表 显示每个月在给定位置的各种类型的部署的员工部署情况 ID Location ID Date NumEmployees DeploymentType ID 例如 一些记录可能是 1 L1 12 2010 7 1 Permanent
  • 同时使用 GUID 和自动递增整数

    我一直在研究使用 GUID 作为数据库中的主键 到目前为止 利似乎大于弊 然而 我发现 GUID 可能不是我想要的 在我的应用程序中 用户应该能够根据用户友好的 ID 来识别对象 因此 例如 如果他们想要获取特定产品而不输入全名 则可以使用
  • PL/pgSQL SELECT 到数组中

    这是我的函数声明和主体的一部分 CREATE OR REPLACE FUNCTION access update RETURNS void AS DECLARE team ids bigint BEGIN SELECT INTO team
  • MySQL“LIKE”搜索不起作用

    我通过 LOAD DATA INFILE 在 MySQL 中导入了一个 txt 数据库 一切似乎都正常 唯一的问题是 如果我使用以下查询在数据库上搜索记录 SELECT FROM hobby WHERE name LIKE Beading
  • 将 .MDF SQL Server 数据库与 ASP.NET 结合使用与使用 SQL Server

    我目前正在 ASP NET MVC 中编写一个网站 我的数据库 其中还没有任何数据 只有正确的表 使用 SQL Server 2008 我已将其安装在我的开发计算机上 我使用服务器资源管理器从应用程序连接到数据库 然后使用 LINQ to
  • SQL Server:从 OPENDATASOURCE 中删除

    这有效 SELECT FROM OPENDATASOURCE Microsoft ACE OLEDB 12 0 Data Source d JobFiles MyFile xlsx Extended properties Excel 8 0
  • 串行类型的外键 - 确保始终手动填充

    我有两个表 国家和地区 CREATE TABLE Countries id SERIAL name VARCHAR 40 NOT NULL PRIMARY KEY id CREATE TABLE Regions id SERIAL coun
  • 删除 IF ELSE 语句中的临时表

    我在这里面临僵局 问题是我必须更改使用 3 个不同临时表的过程 为了便于对话 让我们将它们命名为 temptable1 temptable2 temptable3 我无法在这里复制 粘贴整个过程 但总体思路是这样的 原始过程 procedu
  • PostgreSQL 中“-”处或附近的语法错误

    我正在尝试运行查询来更新用户密码 alter user dell sys with password Pass 133 但因为 它给了我这样的错误 ERROR syntax error at or near LINE 1 alter use
  • 如何使用 Windows 身份验证指定 Windows 用户从 ASP 连接到 MS SQL Server 数据库

    我已经尝试了一个多月的时间来将这里的 ASP 脚本连接到 SQL Server 数据库 但每次我使用这个连接字符串时 Data Source dbServer01 Initial Catalog POS123 Integrated Secu
  • 在c#中创建sql连接

    我是这个网站的新手 也是编程的新手 我目前正在通过销售点创建库存系统 它使用模态和非模态形式 我的问题是 我正在研究change password对话框必须连接到数据库才能覆盖密码字段 我使用的数据库是Microsoft SQL Serve
  • 什么时候应该使用 C++ 而不是 SQL?

    我是一名 C 程序员 偶尔使用 MySQL 来处理数据库 但我的 SQL 知识相当有限 但我肯定愿意改变这一点 目前 我正在尝试仅使用 SQL 查询对数据库中的数据进行分析 但我准备放弃了 转而将数据导入到C 中 用C 代码进行分析 我和同
  • 意外的查询结果

    为什么我从 sql server 得到以下结果 SELECT 12 C1 CONVERT int C2 CASE WHEN THEN equal ELSE not equal END C3 Sql Server Fiddle 演示 http
  • 实现软删除的最佳方法是什么?

    目前在做一个项目 我们要对大部分用户 用户角色 实现软删除 我们决定添加一个is deleted 0 数据库中每个表的字段并将其设置为 1 如果特定用户角色点击特定记录上的删除按钮 现在为了将来的维护 每个SELECT查询需要确保它们不包含
  • 同一索引操作上的不同估计行?

    简介和背景 我必须优化一个简单的查询 下面的示例 重写几次后 我认识到同一个索引操作的估计行数会根据查询的编写方式而有所不同 最初 该查询执行了聚集索引扫描 因为生产中的表包含二进制列 该表相当大 大约 100 GB 并且全表扫描执行起来需
  • 更改列时快速删除并重新创建多个索引、视图、统计信息

    我的 项目 表中有一个 StoreNumber 列 我想将其更改为 NOT NULL 我最近清理了所有旧数据 以便不存在空条目 但是 当我执行以下语句时 由于对各种视图 索引和统计信息的多重依赖 它失败了 ALTER TABLE Proje
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co

随机推荐