DISTINCT 和 DISTINCT ON have completely different semantics.
First the theory
DISTINCT应用于整个元组.计算查询结果后,DISTINCT将从结果中删除任何重复的元组.
例如,假设表R包含以下内容:
#table r;
a | b
---+---
1 | a
2 | b
3 | c
3 | d
2 | e
1 | a
(6排)
Select distinct*from R将导致:
# select distinct * from r;
a | b
---+---
1 | a
3 | d
2 | e
2 | b
3 | c
(5 rows)
请注意,distinct适用于整个投影属性列表:因此
select distinct * from R
在语义上等同于
select distinct a,b from R
你不能发布
select a, distinct b From R
DISTINCT必须遵循SELECT.它适用于整个元组,而不是结果的属性.
DISTINCT ON是postgresql对该语言的补充.它与group by相似,但不完全相同.
它的语法是:
SELECT DISTINCT ON (attributeList) <rest as any query>
例如:
SELECT DISTINCT ON (a) * from R
它的语义可以描述如下.像往常一样计算查询——不使用DISTINCT ON(a)——但在投影结果之前,对当前结果进行排序,并根据DISTINCT ON(类似于group by)中的属性列表将其分组.现在,使用每组中的第一个元组进行投影,忽略其他元组.
例子:
select distinct * from r order by a;
a | b
---+---
1 | a
2 | e
2 | b
3 | c
3 | d
(5 rows)
然后对于a的每个不同值,取第一个元组.这与:
SELECT DISTINCT on (a) * from r;
a | b
---+---
1 | a
2 | b
3 | c
(3 rows)
一些DBMS(最著名的是sqlite)将允许您运行以下查询:
SELECT a,b from R group by a;
这会给你一个类似的结果.
当且仅当从a到b存在函数依赖关系时,Postgresql将允许此查询.换句话说,如果对于关系R的任何实例,每个值或a只有一个唯一元组,则此查询将有效(因此, Select 第一个元组是确定的:只有一个元组).
例如,如果R的主键是a,那么a->;b和:
SELECT a,b FROM R group by a
与以下内容相同:
SELECT DISTINCT on (a) a, b from r;
Now, back to your problem:
第一个问题:
SELECT DISTINCT count(dimension1)
FROM data_table;
计算维度1的计数(数据表中维度1不为空的元组数).这个问题
问题2:
SELECT count(*)
FROM (SELECT DISTINCT ON (dimension1) dimension1
FROM data_table
GROUP BY dimension1) AS tmp_table;
这是查询中的查询.为了清晰起见,让我重写一下:
WITH tmp_table AS (
SELECT DISTINCT ON (dimension1)
dimension1 FROM data_table
GROUP by dimension1)
SELECT count(*) from tmp_table
让我们计算第一个tmp_表.正如我上面提到的,
现在,我们开始了.它再次使用维度1.但是dimension1已经是唯一的了(因为group by).因此
正如您所看到的,以下查询中存在一个等价关系(它适用于具有属性a的任何关系):
SELECT (DISTINCT ON a) a
FROM R
和
SELECT a FROM R group by a
和
SELECT DISTINCT a FROM R
Warning
对于数据库的任何给定实例,在查询中使用DISTINCT ON结果可能是不确定的.
One interesting aspect
Distinct ON emulates a bad behaviour of sqlite in a much cleaner way. Assume that R has two attributes a 和 b:
SELECT a, b FROM R group by a
is an illegal statement in SQL. Yet, it runs on sqlite. It simply takes a r和om value of b from any of the tuples in the group of same values of a.
In Postgresql this statement is illegal. Instead, you must use DISTINCT ON 和 write:
SELECT DISTINCT ON (a) a,b from R
100
当需要访问功能上依赖于group by属性的值时,DISTINCT ON在group by中非常有用.换句话说,如果您知道对于每一组属性,它们总是具有与第三个属性相同的值,那么在该组属性上使用DISTINCT.否则,必须进行连接才能检索第三个属性.