从PostgreSQL 文档:
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
[ * | expression [ [ AS ] output_name ] [, ...] ]
在引用语法的第一行中,您会发现ON 部分是可选的,但它也是引用括号的那个ON 部分。换句话说,除非 ON 存在,否则括号是没有意义的。
所以,对于这个问题,[ON(表达式 [, ...])] 是不相关的。
下面是一些非常简单的测试数据:
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 之后将表达式放在括号内不会改变它的工作方式。
所以,对于这个问题:
刚刚遇到一个 SQL 查询,特别是针对 Postgres 数据库,它使用一个名为“distinct”的函数。即:
select distinct(pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...
DISTINCT 不是函数!并且该示例查询中的括号被忽略。
如果使用可选的[ ON (expression) ]确实会改变结果。
测试一个:
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 子句 ALSO 引用 SELECT DISTINCT ON PostgreSQL 中使用的表达式,否则会产生错误:
错误:SELECT DISTINCT ON 表达式必须匹配初始 ORDER BY 表达式
上面的例子可以在这里看到在 sqlfiddle 上运行
虽然我不想让我的回答过于复杂,但有一个值得一提的问题:
select distinct (foo,fub) from bar;
现在括号做了一些事情,但他们所做的与 distinct 没有直接关系。参见“复杂类型”