SELECT语句

时间:2017-09-10 16:17:58

标签: sql postgresql select

我正在阅读a documentation for postgreSQL SELECT statement,因为我想找到处理SELECT中SQL语句的顺序。

在文档中说:

  

SELECT从零个或多个表中检索行。 SELECT的一般处理如下:(...)

     
  1. (...)SELECT DISTINCT ON消除了在所有指定表达式上匹配的行。 (...)
     
  1. 如果指定了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语句中关键字的位置是否重要?"或其他任何事情,请适当地编辑问题。

1 个答案:

答案 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子句的子查询替换。这可能是其他数据库没有采用类似功能的原因。