在数据分析与业务场景中,SQL的灵活运用往往能让复杂需求迎刃而解,数据去重与日期时间值处理是数据分析中的两个常用操作。
一、DISTINCT去重:让数据“轻装上阵”
核心作用
DISTINCT关键字如同数据世界的“筛子”,通过扫描指定字段,自动过滤重复值,仅保留唯一记录。例如统计用户表中不重复的城市列表,可快速提取关键维度。
注意事项
性能权衡:对海量数据使用DISTINCT可能导致查询效率下降,需结合索引优化或预聚合策略。
字段选择:多字段去重时,需明确业务需求,避免因字段组合的“过度唯一性”丢失有效信息。
与GROUP BY对比:两者均可去重,但DISTINCT更侧重结果集精简,而GROUP BY常搭配聚合函数扩展分析维度。
典型场景
生成报表中的唯一值下拉选项(如地区、品类)。
数据清洗阶段快速定位重复记录。
代码:
--作用于单列去重
select distinct a from table
--作用于多列去重,a、b两列完全一样才会被认为是重复信息
select distinct a,b from table
--统计去重后的记录的数量
select count(distinct a) from table
二、ROW_NUMBER去重:有去有留的去重
在数据处理中常会遇到这样的需求:针对表中某一列进行去重操作,但需要保留其他所有列的数据。使用传统的DISTINCT或GROUP BY无法直接实现,因为当其他列存在差异时会保留多行记录。这时ROW_NUMBER()函数就能完美解决这个问题。
代码:
--ROW_NUMBER() OVER (partition by order by)
--ROW_NUMBER() 函数为每个分组内的每一行分配一个唯一的连续编号。
--分组是通过partition by实现,它指定了分组的列。
--排序是通过order by实现,它指定了行号分配的顺序。
--OVER()中可以只有partition by,也可以只有order by,它们后面的列可以有多个。
--以下代码的表格设定为table表有a,b,c等多列,a列有重复,b列为时间,查询的结果是a列去重,b列显示重复记录里的最新时间
select * from (select *,row_number() over(partition by a order by b) as rulename from table) as rankeddata where rankeddata.rulename=1
二、日期提取:精准定位时间维度
跨数据库适配
SQL Server:CONVERT(data_type , expression)
MySQL:DATE()函数直接截取日期部分。
PostgreSQL:DATE_TRUNC('day', timestamp_column)实现类似效果。
Oracle:TRUNC(datetime_column)快速完成截断。
应用价值
可视化友好:图表展示时,精确到日的数据更易解读。
条件过滤:按天统计订单量、用户活跃数等场景,避免时间戳干扰。
数据归档:按日期分表存储时,提取日期字段可作为分区依据。
代码:
--convert(data_type , expression)
--data_type为数据类型,date表示日期,time表示时间;
--expression可以是列名或其他表达式
select * from table where convert(date,a)=convert(date,'2025-2-26')
三、总结
DISTINCT与日期提取函数是SQL数据处理中的“黄金搭档”:前者确保数据纯净度,后者助力时间维度精细化。实际应用中需结合业务需求与数据库特性灵活选择语法,兼顾效率与准确性。掌握这两项技能,可大幅提升从原始数据到业务洞见的转化效率。