SQL Server 2012中使用EXCEPT与ORDER BY的方法

4
我可以执行这个。
SELECT TOP 10 model, price
FROM PC 
EXCEPT
SELECT TOP 9 model, price
FROM PC ORDER BY price DESC 

但是当我运行这个程序时,我收到了“Order”附近的语法错误。

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
1个回答

5

解释

ORDER BY 子句在两种情况下允许使用:当存在 TOP(或 OFFSET/FETCH)时,以及在一系列查询/子查询中作为单个查询一起运行的最外层查询中。现在,您知道,在没有 TOP 子句的内部查询上下文中不能使用 ORDER BY。但是,当两种情况(TOP vs. 最外层)冲突时,最外层查询上下文优先。

在使用 UNIONEXCEPTINTERSECT 时,期望出现 ORDER BY 的最外层查询上下文是最后一个查询,尽管它适用于整个查询。由于最外层查询上下文规则优先,因此不允许尝试使与这些关键字之一连接的其他子查询有序。

通过将最外层查询上下文移出 EXCEPT 查询,使用派生表,就像您所做的那样,现在允许各个子查询拥有自己的 ORDER BY 子句。

可能的改进

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

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

这样做可以更清晰地表达您的意图,避免重复查询,并有助于未来维护和任何查看查询的开发人员的理解。请记住,我们的代码应该是:

  1. 正确的(包括定义正确性的性能)
  2. 清晰易懂的
  3. 简明扼要的
  4. 快速的

在这里,清晰度要求使用正确的查询关键字,而不是通过某些巧妙的方式实现相同的结果。


谢谢ErikE。在SQL Server文献中,哪里提到了TOP/ORDER BY的优先级?您还忘记在带有OFFSET-FETCH的代码中包括“ORDER BY”。 - Concerned_Citizen
我不知道文献中是否提到了这个优先级。我的陈述是基于对查询解析器行为的分析所做出的。 - ErikE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接