sql-server - SQL Server 2012 将 EXCEPT 与 ORDER BY 结合使用

标签 sql-server

我可以执行这个。

SELECT TOP 10 model, price
FROM PC 
EXCEPT
SELECT TOP 9 model, price
FROM PC ORDER BY price DESC 

但是当我运行这个时,我在“订单”附近遇到语法错误。

SELECT TOP 10 model, price
FROM PC ORDER BY price DESC
EXCEPT
SELECT TOP 9 model, price
FROM PC ORDER BY price DESC 

我必须这样做。为什么上面的方法不起作用?

SELECT * FROM
(
SELECT TOP 10 model, price
FROM PC ORDER BY price DESC
EXCEPT
SELECT TOP 9 model, price
FROM PC ORDER BY price DESC
) X

最佳答案

说明

在两种情况下允许使用 ORDER BY 子句:存在 TOP(或 OFFSET/FETCH)时,以及在最外层查询中一系列查询/子查询,它们一起作为单个查询运行。现在,如您所知,如果没有 TOP 子句,您就无法在内部查询上下文中使用 ORDER BY。但此外,当两种情况(TOP 与最外层)发生冲突时,最外层查询上下文优先。

当使用 UNIONEXCEPTINTERSECT 时,最外层查询上下文,其中需要 ORDER BY ,是最后查询,但它适用于整个查询。不允许尝试使用这些关键字之一对连接到其他子查询的单个子查询进行排序,因为最外层查询上下文规则优先。

正如您所做的那样,通过使用派生表将最外层查询上下文移出 EXCEPTed 查询,各个子查询现在可以拥有自己的单独 ORDER BY 子句。

可能的改进

如果您使用的是 SQL Server 2012 或更高版本,最好仅使用 OFFSETFETCH 关键字来实现您的目标:

SELECT model, price
FROM dbo.PC
ORDER BY price DESC
OFFSET 9 ROWS 
FETCH NEXT 1 ROWS ONLY;

通过这种方式,查询可以更清楚地表达您的意图,您不必重复查询,这些加在一起对于 future 的维护以及任何 future 查看查询的开发人员的理解都是一个巨大的胜利。请记住,我们的代码应该按顺序:

  1. 正确(以及属于正确定义一部分的任何表现)
  2. 清除
  3. 简洁

在这里,清晰性似乎要求使用正确的查询关键字,而不是通过有点老套(尽管聪明)的方式获得相同的结果。

关于sql-server - SQL Server 2012 将 EXCEPT 与 ORDER BY 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29269355/

相关文章:

sql - 单数还是复数数据库表名?

SQL Server INSERT … SELECT 语句无法解析

c# - SQL Server 检查存储过程是否包含 WITH(NOLOCK)

c# - 首先使用 EF 代码映射组合键

sql - 对具有相同标识号的行求和并按自定义顺序排序

sql - 使用表中的索引标准化数据

sql - TSQL 合并如何工作?针对 UPDATE 和 INSERT 的性能

sql - 如何使用 sql server 在特定列上获得不同的插入顺序?

sql - 使用 SQL 来转换和组合字符串

sql - 如何在SQL Server中检查回文