SELECT DISTINCT 用于从数据库表中返回唯一不同的值,它会去除查询结果中的重复行。
基本语法:
SELECT DISTINCT column1, column2, ...
FROM table_name;
假设有以下 employees 表:
| id | name | department | city |
|---|---|---|---|
| 1 | 张三 | 技术部 | 北京 |
| 2 | 李四 | 销售部 | 上海 |
| 3 | 王五 | 技术部 | 北京 |
| 4 | 赵六 | 市场部 | 广州 |
| 5 | 孙七 | 技术部 | 深圳 |
SELECT DISTINCT department
FROM employees;
结果:
department
----------
技术部
销售部
市场部
SELECT DISTINCT city
FROM employees;
结果:
city
----
北京
上海
广州
深圳
SELECT DISTINCT department, city
FROM employees;
结果:
department city
---------- -----
技术部 北京
销售部 上海
市场部 广州
技术部 深圳
注意:这里有两行"技术部",但因为城市不同(北京 vs 深圳),所以都被保留。
如果列包含 NULL 值,DISTINCT 会将多个 NULL 视为相同值,只返回一个 NULL。
示例:
-- 假设 city 列有 NULL 值
SELECT DISTINCT city
FROM employees;
如果数据中有:北京、上海、NULL、广州、NULL
结果将是:北京、上海、NULL、广州
SELECT DISTINCT department
FROM employees
ORDER BY department;
SELECT DISTINCT department
FROM employees
ORDER BY id; -- 错误!id 不在 SELECT 中
-- 正确写法:
SELECT DISTINCT department
FROM employees
ORDER BY department;
-- 统计有多少个不同的部门
SELECT COUNT(DISTINCT department) as dept_count
FROM employees;
结果:
dept_count
----------
3
-- 这两种写法结果相同
SELECT DISTINCT department FROM employees;
SELECT department FROM employees GROUP BY department;
-- 这样可能得不到预期结果
SELECT DISTINCT department, name
FROM employees;
这会返回所有部门-姓名的唯一组合,而不是唯一的部门。
-- 错误写法
SELECT column1, DISTINCT column2 FROM table; -- 语法错误!
-- 正确写法
SELECT DISTINCT column1, column2 FROM table;
SELECT DISTINCT country
FROM users
WHERE country IS NOT NULL
ORDER BY country;
SELECT DISTINCT color
FROM products
WHERE stock > 0;
SELECT DISTINCT customer_id
FROM orders
WHERE order_date >= '2024-01-01';
PostgreSQL 提供了 DISTINCT ON 扩展:
-- 获取每个部门的最新员工记录
SELECT DISTINCT ON (department) *
FROM employees
ORDER BY department, hire_date DESC;
| 场景 | 使用建议 |
|---|---|
| 需要唯一值列表 | 使用 SELECT DISTINCT column |
| 需要统计唯一值数量 | 使用 COUNT(DISTINCT column) |
| 需要分组统计 | 考虑使用 GROUP BY |
| 大数据集性能优化 | 考虑在子查询中使用 DISTINCT |
| 需要保留其他列数据 | 考虑使用窗口函数或 GROUP BY |
最佳实践:
只在需要时使用 DISTINCT 明确知道需要哪些列的唯一组合 在大表上使用时,考虑添加 WHERE 条件限制数据集 定期分析查询性能