Skip to content

PostgreSQL - DISTINCT 关键字

PostgreSQL - 使用 DISTINCT 关键字选择唯一行

Section titled “PostgreSQL - 使用 DISTINCT 关键字选择唯一行”

SELECT 语句中的 DISTINCT 关键字用于从查询结果集中移除重复行,只返回每个唯一行的一个副本。它是数据分析和报告的基本工具。

基本语法将 DISTINCT 应用于 SELECT 列表中的所有列:

SELECT DISTINCT column1, column2, ...
FROM table_name
WHERE [condition];

这将返回 column1、column2 等列中值组合唯一的行。

考虑一个 products 表,它列出了在不同区域销售的产品:

id | product_name | region | price
----+--------------+------------+-------
1 | T-Shirt | North | 20.00
2 | T-Shirt | South | 20.00
3 | Jeans | North | 50.00
4 | Hat | North | 15.00
5 | T-Shirt | North | 20.00
6 | Jeans | West | 55.00

要获取所有已售产品名称的唯一列表,您可以使用:

SELECT DISTINCT product_name FROM products;

这将每个产品名称只返回一次,即使 ‘T-Shirt’ 和 ‘Jeans’ 在表中多次出现。

product_name
--------------
Hat
Jeans
T-Shirt
(3 rows)

如果您将 DISTINCT 应用于多个列,则这些列的组合必须是唯一的:

SELECT DISTINCT product_name, region FROM products;
product_name | region
--------------+--------
T-Shirt | North
Jeans | West
T-Shirt | South
Hat | North
Jeans | North
(5 rows)

PostgreSQL 提供了一个强大而独特的 DISTINCT 扩展,称为 DISTINCT ON (expression)。它允许您根据特定的排序,选择给定表达式中唯一的“第一行”。这对于“查找每个组中最新/最大 N 个”类型的查询非常有用。

SELECT DISTINCT ON (expression1) column1, column2, ...
FROM table_name
ORDER BY expression1, expression2 [ASC | DESC];

关键规则:DISTINCT ON 子句中的表达式必须与 ORDER BY 子句中最左侧的表达式匹配。这是您控制每个不同组中哪一行被视为“第一行”并返回的方式。

示例:查找每个区域中最昂贵的产品

Section titled “示例:查找每个区域中最昂贵的产品”

使用相同的 products 表,我们可以找到每个区域中最昂贵的产品。

SELECT DISTINCT ON (region)
region, product_name, price
FROM products
ORDER BY region, price DESC;

工作原理:查询首先按 region 排序所有行,然后按 price 降序排序。然后,对于每个唯一的 region,它会选取遇到的第一行,由于排序的原因,这一行就是价格最高的行。

region | product_name | price
--------+--------------+-------
North | Jeans | 50.00
South | T-Shirt | 20.00
West | Jeans | 55.00
(3 rows)

DISTINCT 和 GROUP BY 都可以用于生成一组唯一值。但是,它们的主要目的不同:

  • SELECT DISTINCT:当您只是想从结果集中删除重复行时使用。它是一个过滤工具。
  • GROUP BY:当您想对行组执行聚合函数(如 COUNT、SUM、AVG)时使用。它是一个聚合和汇总工具。
  • DISTINCT ON:当您需要从每个组中选择完整的代表性行,而不仅仅是聚合值时,使用此特定情况。

DISTINCT 和 GROUP BY 通常都需要对结果集进行排序或哈希操作,这在非常大的表上可能计算成本很高。请确保这些子句中使用的任何列都尽可能地进行了索引以提高性能。