row_number() over(partition by xx order by xx desc)

一、目的

主要用于根据某个字段对数据分组去重

二、demo

1. 有数据表 duplicate_test 如下

2. 使用 name 作为 key 对数据分组,并增加一列标识序号 idx(根据 时间戳倒序标记序号)

sql 复制代码
select 
    name,
    row_number() over(partition by name order by timestamp desc) as idx,
    value,
    timestamp
from  duplicate_test 
where is_delete = 0

运行结果如下

3. 根据 name 作为 key,取每个分组里的第一条数据,从而实现 去重

sql 复制代码
select * from
(
    select 
        name,
        row_number() over(partition by name order by timestamp desc) as idx,
        value,
        timestamp
    from  duplicate_test 
    where is_delete = 0
) t where idx = 1

运行结果如下:

三、解释

以上sql 中只有一句核心代码:

row_number() over(partition by name order by timestamp desc) as idx

新增一列序号列 row_number(),根据 name 分组,每个分组里根据 timestamp 倒序排序,序号从 1 开始,起个别名 idx

四、sql 测试源码,数据库是 postgresql

sql 复制代码
-- 建表
create table duplicate_test (
    id bigserial NOT NULL,
    name varchar(50) NULL,
    value int2 NULL,
    is_delete int2 NOT NULL DEFAULT 0,
    timestamp timestamp(6)  NULL
);

-- 插入数据
insert into duplicate_test
(name, value, is_delete, timestamp)
VALUES('One', 11, 0, '2023-01-01 00:00:00');

insert into duplicate_test
(name, value, is_delete, timestamp)
VALUES('One', 22, 0, '2023-02-01 00:00:00');

insert into duplicate_test
(name, value, is_delete, timestamp)
VALUES('Two', 33, 0, '2023-01-01 00:00:00');

insert into duplicate_test
(name, value, is_delete, timestamp)
VALUES('Two', 44, 0, '2023-03-01 00:00:00');

insert into duplicate_test
(name, value, is_delete, timestamp)
VALUES('Two', 55, 0, '2023-05-01 00:00:00');

-- 分组排序
select 
    name,
    row_number() over(partition by name order by timestamp desc) as idx,
    value,
    timestamp
from  duplicate_test 
where is_delete = 0

-- 取每个组里的 时间戳最新的数据
select name, value from
(
    select 
        name,
        row_number() over(partition by name order by timestamp desc) as idx,
        value,
        timestamp
    from  duplicate_test 
    where is_delete = 0
) t where idx = 1

五、参考链接

Hive(十一)--数据去重及row_number()_hive row_number_zxfBdd的博客-CSDN博客

sql - 使用 ROW_NUMBER 和 PARTITION BY 获取第一行和最后一行 - SegmentFault 思否

相关推荐
一只fish22 分钟前
MySQL 8.0 OCP 1Z0-908 题目解析(17)
数据库·mysql
花好月圆春祺夏安1 小时前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式
A__tao1 小时前
SQL 转 Java 实体类工具
java·数据库·sql
m0_653031361 小时前
腾讯云认证考试报名 - TDSQL数据库交付运维专家(TCCE PostgreSQL版)
运维·数据库·腾讯云
小马哥编程2 小时前
【iSAQB软件架构】架构决策记录-ADR
数据库·架构·系统架构·设计规范
萧鼎2 小时前
深度探索 Py2neo:用 Python 玩转图数据库 Neo4j
数据库·python·neo4j
m0_653031363 小时前
腾讯云认证考试报名 - TDSQL数据库交付运维专家(TCCE MySQL版)
运维·数据库·腾讯云
power 雀儿3 小时前
集群聊天服务器---MySQL数据库的建立
服务器·数据库·mysql
骑着王八撵玉兔5 小时前
【性能优化与架构调优(二)】高性能数据库设计与优化
数据库·性能优化·架构
想要入门的程序猿6 小时前
Qt写入excel
数据库·qt·excel