我可以执行这个。
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
与最外层)发生冲突时,最外层查询上下文优先。
当使用 UNION
、EXCEPT
和 INTERSECT
时,最外层查询上下文,其中需要 ORDER BY
,是最后查询,但它适用于整个查询。不允许尝试使用这些关键字之一对连接到其他子查询的单个子查询进行排序,因为最外层查询上下文规则优先。
正如您所做的那样,通过使用派生表将最外层查询上下文移出 EXCEPT
ed 查询,各个子查询现在可以拥有自己的单独 ORDER BY
子句。
可能的改进
如果您使用的是 SQL Server 2012 或更高版本,最好仅使用 OFFSET
和 FETCH
关键字来实现您的目标:
SELECT model, price
FROM dbo.PC
ORDER BY price DESC
OFFSET 9 ROWS
FETCH NEXT 1 ROWS ONLY;
通过这种方式,查询可以更清楚地表达您的意图,您不必重复查询,这些加在一起对于 future 的维护以及任何 future 查看查询的开发人员的理解都是一个巨大的胜利。请记住,我们的代码应该按顺序:
- 正确(以及属于正确定义一部分的任何表现)
- 清除
- 简洁
- 快
在这里,清晰性似乎要求使用正确的查询关键字,而不是通过有点老套(尽管聪明)的方式获得相同的结果。
关于sql-server - SQL Server 2012 将 EXCEPT 与 ORDER BY 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29269355/