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 思否

相关推荐
爱吃烤鸡翅的酸菜鱼1 小时前
MySQL初学之旅(1)配置与基础操作
java·数据库·mysql·database
三日看尽长安花3 小时前
【分布式数据库】
数据库·分布式
一 乐7 小时前
家常菜点餐|基于java和小程序的家庭大厨家常菜点餐系统设计与实现(源码+数据库+文档)
java·数据库·小程序·家庭点餐小程序·家庭家常菜点餐
小小不董8 小时前
Oracle OCP认证考试考点详解082系列08
linux·运维·服务器·数据库·oracle·dba
王哲晓8 小时前
第一章 微服务入门
java·数据库·微服务
DarkAthena8 小时前
【MogDB】MogDB5.2.0重磅发布第五篇-支持部分ORACLE的HINT
数据库·oracle·opengauss
PythonFun8 小时前
Python常用脚本集锦
java·数据库·python
wang09079 小时前
netty之实现一个redis的客户端
数据库·redis·缓存
LeonNo119 小时前
【软考】Redis不同的数据类型和应用场景。
数据库·redis·缓存
宝哥大数据9 小时前
数据仓库设计-分层
大数据·数据库·数据仓库