SQL SELECT DISTINCT 语句详解
1. 什么是 SELECT DISTINCT?
SELECT DISTINCT 用于从数据库表中返回唯一不同的值,它会去除查询结果中的重复行。
基本语法:
SELECT DISTINCT column1, column2, ...
FROM table_name;
2. 简单示例
假设有以下 employees 表:
| id |
name |
department |
city |
|---|
| 1 |
张三 |
技术部 |
北京 |
| 2 |
李四 |
销售部 |
上海 |
| 3 |
王五 |
技术部 |
北京 |
| 4 |
赵六 |
市场部 |
广州 |
| 5 |
孙七 |
技术部 |
深圳 |
示例 1:获取唯一的部门名称
SELECT DISTINCT department
FROM employees;
结果:
department
----------
技术部
销售部
市场部
示例 2:获取唯一的城市
SELECT DISTINCT city
FROM employees;
结果:
city
----
北京
上海
广州
深圳
3. 多列 DISTINCT
示例 3:获取部门-城市组合的唯一值
SELECT DISTINCT department, city
FROM employees;
结果:
department city
---------- -----
技术部 北京
销售部 上海
市场部 广州
技术部 深圳
注意:这里有两行"技术部",但因为城市不同(北京 vs 深圳),所以都被保留。
4. DISTINCT 与 NULL 值
如果列包含 NULL 值,DISTINCT 会将多个 NULL 视为相同值,只返回一个 NULL。
示例:
-- 假设 city 列有 NULL 值
SELECT DISTINCT city
FROM employees;
如果数据中有:北京、上海、NULL、广州、NULL
结果将是:北京、上海、NULL、广州
5. DISTINCT 与 ORDER BY
示例 4:排序 DISTINCT 结果
SELECT DISTINCT department
FROM employees
ORDER BY department;
示例 5:按非 DISTINCT 列排序
SELECT DISTINCT department
FROM employees
ORDER BY id; -- 错误!id 不在 SELECT 中
-- 正确写法:
SELECT DISTINCT department
FROM employees
ORDER BY department;
6. DISTINCT 与聚合函数
示例 6:统计唯一值数量
-- 统计有多少个不同的部门
SELECT COUNT(DISTINCT department) as dept_count
FROM employees;
结果:
dept_count
----------
3
7. 性能注意事项
DISTINCT 会降低查询性能,因为它需要对结果集进行排序和去重
在大表上使用 DISTINCT 时要注意性能影响
有时可以用 GROUP BY 替代:
-- 这两种写法结果相同
SELECT DISTINCT department FROM employees;
SELECT department FROM employees GROUP BY department;
8. 常见错误与误区
错误 1:在包含非重复列的查询中使用 DISTINCT
-- 这样可能得不到预期结果
SELECT DISTINCT department, name
FROM employees;
这会返回所有部门-姓名的唯一组合,而不是唯一的部门。
错误 2:DISTINCT 位置错误
-- 错误写法
SELECT column1, DISTINCT column2 FROM table; -- 语法错误!
-- 正确写法
SELECT DISTINCT column1, column2 FROM table;
9. 实际应用场景
场景 1:获取网站的所有国家/地区列表
SELECT DISTINCT country
FROM users
WHERE country IS NOT NULL
ORDER BY country;
场景 2:获取产品的所有颜色选项
SELECT DISTINCT color
FROM products
WHERE stock > 0;
场景 3:查找有订单的所有客户
SELECT DISTINCT customer_id
FROM orders
WHERE order_date >= '2024-01-01';
10. 高级用法:DISTINCT ON (PostgreSQL)
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 条件限制数据集
定期分析查询性能