我正在阅读a documentation for postgreSQL SELECT statement,因为我想找到处理SELECT中SQL语句的顺序。
在文档中说:
SELECT从零个或多个表中检索行。 SELECT的一般处理如下:(...)
- (...)SELECT DISTINCT ON消除了在所有指定表达式上匹配的行。 (...)
- 如果指定了ORDER BY子句,则返回的行按指定的顺序排序。 (...)
它进一步说(在DISTINCT clause description中):
使用与之相同的规则解释DISTINCT ON表达式 对于ORDER BY(见上文)。注意"第一行"每组都是 不可预测,除非使用ORDER BY来确保所需的行 首先出现。 (...)
DISTINCT ON表达式必须与最左边的ORDER BY表达式匹配。 ORDER BY子句通常包含其他表达式,用于确定每个DISTINCT ON组中行的所需优先级。
我自然期望ORDER BY应该修改DISTINCT ON的结果,并且因为DISTINCT ON可能(并且可能会)给出不可预测的结果,所以 - 简单地说 - 如果没有前面的另一个SELECT查询那么就没用了。
SELECT语句中语句的实际执行顺序是什么? 特别是:为什么在DISTINCT ON之前处理ORDER BY?
我不是postgreSQL和SQL的有经验的用户,因此我不知道我是否提出了正确的问题(XY Problem)。如果您认为这个问题应该是" DISTINCT如何工作?"或者甚至" SELECT语句中关键字的位置是否重要?"或其他任何事情,请适当地编辑问题。
答案 0 :(得分:1)
首先“处理顺序”在SQL中有点误导。在执行之前,语句是编译的。实际执行可能看起来与SQL本身非常不同(事实上,执行表示为DAG指导的非循环图 - 看起来与SELECT
语法完全不同)。
DISTINCT ON
是Postgres扩展程序。它非常方便 - 让您在括号中每个值获得一行。并且,您可以控制哪一行。
假设你有这样的数据:
a b c
A1 3 1
A1 2 2
A1 4 3
A2 6 4
A2 1 5
如果要指定每个值需要一个行,请使用distinct on
。而且,它让你指定你想要的值。例如,要为每个b
获取a
的最低值:
select distinct on (a) a, b, c
from t
order by a, b asc;
为每个b
获取a
的最高值:
select distinct on (a) a, b, c
from t
order by a, b desc;
括号中的表达式需要匹配order by
中前导表达式的表达式。
通过阅读文档,您无法了解其工作原理。你需要使用它。
此功能可以由外部查询中带有row_number()
和where
子句的子查询替换。这可能是其他数据库没有采用类似功能的原因。