来自PostgreSQL文档:
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
[ * | expression [ [ AS ] output_name ] [, ...] ]
在引用的语法的第一行中,您会发现ON部分是可选的,但是也正是这个ON部分引用了括号。换句话说,除非有ON存在,否则括号是没有意义的。
因此,对于这个问题,[ ON ( expression [, ...] ) ]不相关。
这里是一些非常简单的测试数据:
CREATE TABLE bar
(foo varchar(3), fub varchar(1), flut timestamp)
;
INSERT INTO bar
(foo, fub, flut)
VALUES
('one', 'a', '2016-01-01 01:01:03'),
('one', 'b', '2016-01-01 01:01:02'),
('one', 'c', '2016-01-01 01:01:01'),
('two', 'd', '2016-01-01 01:01:03'),
('two', 'e', '2016-01-01 01:01:02'),
('two', 'f', '2016-01-01 01:01:01')
;
让我们首先集中注意括号。在select后面跟着一个表达式时,单独使用括号会产生什么效果?例如:
select (foo) from bar;
| foo |
|-----|
| one |
| one |
| one |
| two |
| two |
| two |
我相信你会发现这个结果与不使用括号包围列foo的查询完全相同,所以我们从那个查询中得到的结论是括号没有任何作用。然而,如果我们引入DISTINCT会发生什么呢?
select distinct(foo) from bar;
| foo |
|-----|
| two |
| one |
select distinct foo from bar;
| foo |
|-----|
| two |
| one |
我们再次看到,括号根本没有任何影响。如果我们回顾一下语法,这是一致的。DISTINCT不是函数,在DISTINCT后面放置一个表达式括号并不会改变它的工作方式。
所以,对于这个问题:
我刚刚遇到了一个针对Postgres数据库的SQL查询,使用了一个名为“distinct”的函数。即:
select distinct(pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...
DISTINCT不是一个函数!并且在该示例查询中,括号会被忽略。
如果使用可选的[ ON (expression) ],确实会改变结果。
测试a:
select distinct ON (foo) foo, fub, flut from bar order by foo
| foo | fub | flut |
|-----|-----|---------------------------|
| one | a | January, 01 2016 01:01:03 |
| two | d | January, 01 2016 01:01:03 |
测试 b:
select distinct ON (fub) foo, fub, flut from bar order by fub
| foo | fub | flut |
|-----|-----|---------------------------|
| one | a | January, 01 2016 01:01:03 |
| one | b | January, 01 2016 01:01:02 |
| one | c | January, 01 2016 01:01:01 |
| two | d | January, 01 2016 01:01:03 |
| two | e | January, 01 2016 01:01:02 |
| two | f | January, 01 2016 01:01:01 |
测试c:
select distinct ON (flut) foo, fub, flut from bar order by flut
| foo | fub | flut |
|-----|-----|---------------------------|
| one | c | January, 01 2016 01:01:01 |
| one | b | January, 01 2016 01:01:02 |
| one | a | January, 01 2016 01:01:03 |
[ ON (expression) ] 功能非常有用,因为它可以在不同的列表中提供“第一个”、“最后一个”、“最早的”或“最近的”行。但请记住,此功能与 ORDER BY 子句耦合,实际上,除非 ORDER BY 子句还引用 SELECT DISTINCT ON PostgreSQL 中使用的表达式,否则会产生错误:
ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY
expressions
上面的示例可以在 sqlfiddle 这里 运行。
虽然我不想复杂化我的回答,但有一点需要提及:
select distinct (foo,fub) from bar;
现在括号有作用了,但它们所做的与distinct没有直接关系。请参见“复杂类型”