0Pricing
SQL Academy · 课时

多列上的 DISTINCT

确保组合值唯一

多列上的 DISTINCT 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

为什么要使用多列

您已经知道 SELECT DISTINCT 会移除重复行。但是,当查询返回多列时,“重复”意味着什么呢?

只有当每个选中的列都与另一行的对应值相同时,一行才会被视为重复行。只要有一列不同,两行都会保留。

示例表:订单

我们来创建一个小型订单表进行尝试。它记录了哪位客户购买了哪种类别的商品,以及购买发生在哪个国家。

CREATE TABLE orders (
  id         INTEGER,
  customer   VARCHAR(50),
  category   VARCHAR(50),
  country    VARCHAR(50)
);

INSERT INTO orders VALUES
  (1, 'Alice', 'Electronics', 'US'),
  (2, 'Alice', 'Books',       'US'),
  (3, 'Bob',   'Electronics', 'UK'),
  (4, 'Alice', 'Electronics', 'US'),
  (5, 'Bob',   'Electronics', 'UK'),
  (6, 'Carol', 'Clothing',    'CA');

单列 DISTINCT

快速回顾一下:对单列使用 DISTINCT,只会返回该列的每个唯一值。

这里我们得到每个唯一的客户名称——虽然有六笔订单,但结果只有三行。

SELECT DISTINCT customer
FROM orders;

双列 DISTINCT

现在添加第二列。关键字 DISTINCT 仍然只需在 SELECT 后出现一次。数据库会将<​​strong>每个唯一的(客户、类别)组合视为一行。

艾丽丝出现了两次——一次对应电子产品,一次对应图书——因为这是两个不同的组合。

SELECT DISTINCT customer, category
FROM orders;

如何检查唯一性

数据库会比较完整的行快照。要让 DISTINCT 消除一行,SELECT 列表中的所有列都必须与已经出现过的某一行完全匹配。

在我们的订单表中,第 3 行和第 5 行都是(鲍勃、电子产品、UK)——三列完全匹配,因此其中一行会被消除。

SELECT DISTINCT customer, category, country
FROM orders;
-- Row (Bob, Electronics, UK) appears only once
-- even though it occurs on rows 3 and 5

部分匹配不会被消除

艾丽丝有两行的 category = Electronics,但它们的 country = US。选中全部三列时,这两行原始数据完全相同,因此只会保留一行。

改变选中的列,唯一性判断也会随之改变。

-- Select only customer + country
-- (Alice, US) appears twice in the table but DISTINCT keeps it once
SELECT DISTINCT customer, country
FROM orders;

-- Now add category back — uniqueness recalculated
SELECT DISTINCT customer, category, country
FROM orders;

实际应用场景:唯一组合

一种常见模式是找出每一组唯一的两个属性组合——例如,不考虑每种销售记录出现的次数,找出哪些产品类别在哪些国家有售。

SELECT DISTINCT category, country
FROM orders
ORDER BY category, country;

将 DISTINCT 与 WHERE 结合

您可以先用 WHERE 筛选行,然后由 DISTINCT 从筛选结果中移除重复项。这两个子句彼此独立地工作——WHERE 缩小数据范围,DISTINCT 对其去重。

SELECT DISTINCT customer, category
FROM orders
WHERE country = 'US';

DISTINCT 与 GROUP BY 的比较

获取唯一组合的另一种等效方式是使用 GROUP BY。对于简单去重,这两种方式会产生相同的结果。当您需要聚合值时,差异就很重要了:GROUP BY 允许您添加 COUNT(*)、SUM() 等函数,而 DISTINCT 不支持。

-- Using DISTINCT
SELECT DISTINCT customer, category
FROM orders;

-- Equivalent using GROUP BY
SELECT customer, category
FROM orders
GROUP BY customer, category;

统计唯一组合

将多列 DISTINCT 包裹在子查询中,可以统计存在多少个唯一组合。这是衡量数据多样性的实用方法。

SELECT COUNT(*) AS unique_customer_category_pairs
FROM (
  SELECT DISTINCT customer, category
  FROM orders
) AS deduped;

常见错误:DISTINCT 适用于所有列

一个常见误解是,DISTINCT 只适用于列出的第一列。事实并非如此。 DISTINCT 始终会考虑由所有选定列构成的整行。

您无法只对部分列使用 DISTINCT,同时保留其他列中的重复项——为此,您需要使用诸如 ROW_NUMBER() 这样的窗口函数。

-- This does NOT give distinct customers with any category
-- It gives distinct (customer, category) pairs
SELECT DISTINCT customer, category
FROM orders;

-- If you want one row per customer (any category), use:
SELECT customer, MIN(category) AS sample_category
FROM orders
GROUP BY customer;

快速检查

请测试您对多列 DISTINCT 的理解。

课程回顾

做得很好!以下是您对在多列上使用 DISTINCT 的学习内容:

  • DISTINCT 作用于整行——会一起检查所有选定列。
  • 仅当每一列都与之前已出现的某行完全匹配时,才会删除该行。
  • 从 SELECT 列表中添加或移除列,会改变哪些行被视为重复行。
  • 您可以自由地将 DISTINCT 与 WHERE 和 ORDER BY 结合使用。
  • GROUP BY 是等效的替代方案,并且在您还需要聚合时是必需的。

掌握多列 DISTINCT 后,您就能高效探索任何数据集中的唯一组合。

常见问题解答

「多列上的 DISTINCT」课时是免费的吗?

是的 — 「多列上的 DISTINCT」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「多列上的 DISTINCT」这节课中我会学到什么?

确保组合值唯一 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「多列上的 DISTINCT」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. SELECT DISTINCT 基础
  2. 多列上的 DISTINCT
  3. PostgreSQL DISTINCT ON
  4. 统计不重复值
← 返回 SQL Academy