X-Dragon版权所有
Email : [email protected]
参考:https://www.cnblogs.com/xuena/p/3912234.html
1 分类
- 重复分两种。
- 一是完全重复的记录,也即所有字段均重复的记录,
- 二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。
2 表数据
- 用户办理套餐的记录表,可看出,user_id=33333有两条完全重复的记录,user_id=11111的tc_name和open_date不一样
建表SQL
/*
为了方便书写 笔者本地没DB2 用MYSQL应付一下
SQLyog Ultimate v12.5.0 (64 bit)
MySQL - 8.0.11
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
create table `distinct_table` (
`USER_ID` varchar (30),
`NAME` varchar (30),
`TC_NAME` varchar (60),
`open_date` date
);
CREATE TABLE `distinct` (
`USER_ID` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`NAME` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`TC_NAME` varchar(20) DEFAULT NULL,
`open_date` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into `distinct_table` (`USER_ID`, `NAME`, `TC_NAME`, `open_date`) values('11111','1','动感地带','2013-07-01');
insert into `distinct_table` (`USER_ID`, `NAME`, `TC_NAME`, `open_date`) values('11111','1','全球通','2014-06-08');
insert into `distinct_table` (`USER_ID`, `NAME`, `TC_NAME`, `open_date`) values('22222','2','神州行','2014-03-01');
insert into `distinct_table` (`USER_ID`, `NAME`, `TC_NAME`, `open_date`) values('33333','3','全球通','2013-02-01');
insert into `distinct_table` (`USER_ID`, `NAME`, `TC_NAME`, `open_date`) values('33333','3','全球通','2013-02-01');
3 去重SQL
1、完全重复,使用distinct或group by
-- 1、完全去重 使用distinct--
SELECT DISTINCT USER_ID,NAME,TC_NAME,OPEN_DATE FROM DISTINCT_TABLE;
-- 2、完全重复 用group by 该方法也只对完全重复的记录有效--
SELECT USER_ID,NAME,TC_NAME,OPEN_DATE FROM DISTINCT_TABLE GROUP BY USER_ID,NAME,TC_NAME,OPEN_DATE;
2、部分重复 max聚合函数
- 该方法得出的结果如下,对完全重复记录和部分重复记录都有效
- 注:部分重复的记录要对所有重复字段使用max或min等才有效
-- 3、max等聚合函数 --
SELECT
user_id,NAME,MAX(tc_name),MAX(open_date)
FROM
DISTINCT_TABLE
GROUP BY
user_id,NAME
-- 按照USER_ID, NAME区分 去掉所有和部分重复--
SELECT
user_id, NAME, MAX(TC_NAME) AS TC_NAME, MAX(open_date)
FROM DISTINCT_TABLE
GROUP BY USER_ID, NAME;
-- 仅去掉所有重复 --
SELECT
MAX(USER_ID), MAX(NAME), MAX(TC_NAME)AS TC_NAME, MAX(OPEN_DATE) AS OPEN_DATE
FROM DISTINCT_TABLE
GROUP BY USER_ID, NAME,TC_NAME,OPEN_DATE;
3、row_number()over() 分等级之后限定 row=1
-- 3、row_number()over() 分等级之后限定 row=1 MYSQL语法报错 DB2应该可以--
SELECT
user_id,NAME,tc_name,open_date
FROM
(
SELECT
user_id,NAME,tc_name,open_date,row_number() over(PARTITION BY user_id ORDER BY open_date DESC) AS ROW
FROM
DISTINCT_TABLE
)
WHERE ROW=1