欢迎光临重庆雪聪网
详情描述
SQL SELECT DISTINCT 去重的实现

SQL 中的 SELECT DISTINCT 用于从查询结果中去除重复的行,返回唯一值。以下是几种常见的实现方式:

1. 基本 DISTINCT 用法

单列去重

SELECT DISTINCT column_name 
FROM table_name;

多列去重

SELECT DISTINCT column1, column2, column3
FROM table_name;

这会基于所有指定列的 组合 来去重。

2. DISTINCT 与聚合函数

-- 统计不重复的个数
SELECT COUNT(DISTINCT column_name) 
FROM table_name;

-- 可以与多个聚合函数结合
SELECT 
    COUNT(DISTINCT category) as unique_categories,
    AVG(DISTINCT price) as avg_unique_price
FROM products;

3. 替代方案:GROUP BY

GROUP BY 也可以实现类似效果,通常用于需要聚合数据时:

-- 等同于 SELECT DISTINCT column1, column2
SELECT column1, column2
FROM table_name
GROUP BY column1, column2;

-- 结合聚合函数
SELECT column1, COUNT(*)
FROM table_name
GROUP BY column1;

4. 窗口函数去重(ROW_NUMBER)

对于更复杂的去重逻辑(如保留最新记录):

-- 保留每个分组中的第一条记录
WITH ranked_data AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY column1, column2 ORDER BY id) as rn
    FROM table_name
)
SELECT column1, column2, column3
FROM ranked_data
WHERE rn = 1;

5. 实际示例

示例数据表 employees

id name department salary
1 Alice IT 5000
2 Bob HR 4500
3 Alice IT 5000
4 Charlie IT 5500
-- 获取所有不重复的部门
SELECT DISTINCT department 
FROM employees;
-- 结果: IT, HR

-- 获取不重复的姓名和部门组合
SELECT DISTINCT name, department 
FROM employees;
-- 结果: (Alice, IT), (Bob, HR), (Charlie, IT)

-- 统计不重复的姓名数量
SELECT COUNT(DISTINCT name) 
FROM employees;
-- 结果: 3

6. 性能注意事项

DISTINCT 与 GROUP BY 性能

  • 现代数据库优化器通常将两者视为等价
  • 但在某些情况下,GROUP BY 可能更快(特别是需要聚合时)

索引优化

-- 为经常去重的列创建索引
CREATE INDEX idx_column ON table_name(column_name);

NULL 值处理

  • DISTINCT 将多个 NULL 值视为相同
  • 结果中只会出现一个 NULL

7. 复杂去重场景

-- 去重并排序
SELECT DISTINCT column_name
FROM table_name
ORDER BY column_name;

-- 去重并限制结果数
SELECT DISTINCT column_name
FROM table_name
LIMIT 10;

-- 使用子查询去重
SELECT *
FROM table1 t1
WHERE t1.id IN (
    SELECT DISTINCT table1_id
    FROM table2
);

8. 各数据库方言差异

PostgreSQL

-- 使用 DISTINCT ON 按指定列去重,保留每组的第一行
SELECT DISTINCT ON (department) id, name, department
FROM employees
ORDER BY department, salary DESC;

MySQL

-- MySQL 8.0+ 支持窗口函数
-- 较早版本可能需要使用 GROUP BY 或临时表

最佳实践建议

明确去重需求:确定是基于单列还是多列组合去重 考虑 NULL:理解 NULL 值在去重中的处理方式 性能测试:大数据量时测试不同方法的性能 结合业务逻辑:可能需要保留特定行而非简单去重 避免过度使用:不必要的 DISTINCT 会增加查询开销

选择哪种方法取决于具体需求、数据量、数据库类型和性能要求。对于简单去重,SELECT DISTINCT 通常是最直观的选择;对于需要聚合或复杂逻辑的去重,考虑使用 GROUP BY 或窗口函数。

相关帖子
通过“带押过户”方式交易,需要缴纳的税费和传统交易方式有什么不同吗?
通过“带押过户”方式交易,需要缴纳的税费和传统交易方式有什么不同吗?
自家阳台上的花盆被大风吹落砸到人,业主需要承担法律责任吗?
自家阳台上的花盆被大风吹落砸到人,业主需要承担法律责任吗?
Zabbix对Kafka topic积压数据监控的解决方案
Zabbix对Kafka topic积压数据监控的解决方案
宝宝口腔溃疡会吐吗
宝宝口腔溃疡会吐吗
当我们谈论生育率时,除了数字,更应关注哪些关于儿童成长的环境因素?
当我们谈论生育率时,除了数字,更应关注哪些关于儿童成长的环境因素?
2026年消费券发放后,对激发消费市场活力产生了哪些阶段性影响?
2026年消费券发放后,对激发消费市场活力产生了哪些阶段性影响?
2026年支持农产品上行的快递网点,在包装和运输上有哪些特殊措施?
2026年支持农产品上行的快递网点,在包装和运输上有哪些特殊措施?
2026年各地实施的峰谷电价政策,会如何具体影响电动汽车的充电成本?
2026年各地实施的峰谷电价政策,会如何具体影响电动汽车的充电成本?
如果两个人靠得很近,他们的影子会融合吗?这其中有什么有趣的科学规律?
如果两个人靠得很近,他们的影子会融合吗?这其中有什么有趣的科学规律?
村民操办红白事时,使用村委会广场等公共资源,其合理范围是什么?
村民操办红白事时,使用村委会广场等公共资源,其合理范围是什么?
带薪年休假期间的工资,是按照基本工资还是平均工资来计算?
带薪年休假期间的工资,是按照基本工资还是平均工资来计算?
工会组织的职工疗休养活动通常如何安排,参与资格和流程在近年有何变化?
工会组织的职工疗休养活动通常如何安排,参与资格和流程在近年有何变化?
对于心智障碍者,2026年有哪些数字工具或设计方法可以帮助他们理解复杂信息?
对于心智障碍者,2026年有哪些数字工具或设计方法可以帮助他们理解复杂信息?
AI怎么画简笔画竹笋? ai快速手绘山竹笋形状图案的技巧
AI怎么画简笔画竹笋? ai快速手绘山竹笋形状图案的技巧
小体量博主在2026年应关注哪些比流量更重要的核心成长指标?
小体量博主在2026年应关注哪些比流量更重要的核心成长指标?
患者的病历资料中,是否包含所有检查报告、医嘱记录和手术过程记录?
患者的病历资料中,是否包含所有检查报告、医嘱记录和手术过程记录?
ClickHouse使用MySQL数据库引擎的实现
ClickHouse使用MySQL数据库引擎的实现
在2026年,自由职业者或平台骑手如何为自己配置类似工伤保险的保障?
在2026年,自由职业者或平台骑手如何为自己配置类似工伤保险的保障?