DISTINCT 子句
如果指定了 SELECT DISTINCT
,则查询结果中将仅保留唯一行。因此,在结果中所有完全匹配的行集合中,仅会保留单行。
您可以指定必须具有唯一值的列列表:`SELECT DISTINCT ON (column1, column2,...)`。如果未指定列,则将考虑所有列。
考虑下表
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
使用 `DISTINCT` 而不指定列
SELECT DISTINCT * FROM t1;
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
使用 `DISTINCT` 并指定列
SELECT DISTINCT ON (a,b) * FROM t1;
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
DISTINCT 和 ORDER BY
ClickHouse 支持在一个查询中对不同列使用 `DISTINCT` 和 `ORDER BY` 子句。`DISTINCT` 子句在 `ORDER BY` 子句之前执行。
考虑下表
┌─a─┬─b─┐
│ 2 │ 1 │
│ 1 │ 2 │
│ 3 │ 3 │
│ 2 │ 4 │
└───┴───┘
选择数据
SELECT DISTINCT a FROM t1 ORDER BY b ASC;
┌─a─┐
│ 2 │
│ 1 │
│ 3 │
└───┘
选择具有不同排序方向的数据
SELECT DISTINCT a FROM t1 ORDER BY b DESC;
┌─a─┐
│ 3 │
│ 1 │
│ 2 │
└───┘
行 `2, 4` 在排序前被截断。
在编写查询时,请考虑此实现特性。
Null 处理
`DISTINCT` 对待 NULL 的方式如同 NULL
是一个特定值,并且 NULL==NULL
。换句话说,在 DISTINCT
结果中,与 NULL
的不同组合仅出现一次。这与大多数其他上下文中的 NULL
处理不同。
替代方案
可以通过在与 SELECT
子句指定的相同值集上应用 GROUP BY 来获得相同的结果,而无需使用任何聚合函数。但是,与 GROUP BY
方法相比,存在一些差异