《数据库》表整行数据去重LISTAGG函数

数据去重方案

oracle列转行函数LISTAGG

背景:在订单操作历史表中查询出最早操作改订单的人.

思考:百度搜索oracle列转行函数LISTAGG,然后再截取,达到去重。可是mysql库没有这样的函数。在去搜索mysql的类似方式,发现用GROUP_CONCAT 、GROUP和 ORFER BY 关键字即可实现。发现oracle 去重也有另一个方法去实现行去重 。

1.1 oracle列转行函数LISTAGG用

-- Create table
create table TBL_A
(
  col_id           NVARCHAR2(32) not null,
  col_order_id     NVARCHAR2(64),
  col_creator      NVARCHAR2(64),
  col_created_time DATE
)tablespace USERS;
-- Create/Recreate primary, unique and foreign key constraints 
alter table TBL_A
  add constraint COL_ID primary key (COL_ID)
  using index 
  tablespace USERS;
  insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1001', 'd1001', '张三', to_date('15-07-2022 16:43:54', 'dd-mm-yyyy hh24:mi:ss'));
insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1002', 'd1001', '李四', to_date('16-07-2022 16:44:51', 'dd-mm-yyyy hh24:mi:ss'));
insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1003', 'd1001', '王五', to_date('17-07-2022 16:45:42', 'dd-mm-yyyy hh24:mi:ss'));
insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1004', 'd1002', '诸葛', to_date('18-07-2022 16:43:54', 'dd-mm-yyyy hh24:mi:ss'));
insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1005', 'd1002', '赵云', to_date('16-07-2022 16:44:51', 'dd-mm-yyyy hh24:mi:ss'));
insert into tbl_a (COL_ID, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME)
values ('1006', 'd1002', '曹操', to_date('17-07-2022 16:45:42', 'dd-mm-yyyy hh24:mi:ss'));

listagg 最基本用法

SELECT listagg(to_char(col_creator),',') within group(order by col_created_time) name from tbl_a;

-- 结果:  name 
--       张三,李四,赵云,曹操,王五,诸葛

分组用法

SELECT col_order_id,listagg(to_char(col_creator),',') within group(order by col_created_time) NAME from tbl_a group by col_order_id;
-- 结果
  row_number col_order_id       NAME
-- 1	     d1001	         张三,李四,王五
-- 2	     d1002	         赵云,曹操,诸葛

查询出最早操作改订单的人

SELECT M, COL_ORDER_ID, COL_CREATOR, COL_CREATED_TIME
  FROM (SELECT ROW_NUMBER() OVER(PARTITION BY COL_ORDER_ID ORDER BY COL_CREATED_TIME DESC) M,
               COL_ORDER_ID,
               COL_CREATOR,
               COL_CREATED_TIME  FROM TBL_A)
WHERE M = 1

mysql 替代方式

GROUP_CONCAT行转列

select col_order_id,GROUP_CONCAT(col_creator order by col_created_time) col_creator
from tbl_a group by col_order_id;

-- 结果
col_order_id        col_creator
d1001,              "张三,李四,王五"
d1002,              "赵云,曹操,诸葛"

实现数据去重

select col_order_id,SUBSTRING_INDEX(GROUP_CONCAT(col_creator order by col_created_time),',',1) col_creator
from tbl_a group by col_order_id;


-- 结果
col_order_id  col_creator
d1001,        张三
d1002,        赵云

建表语句

create table tbl_a
(
    col_id           varchar(32) not null
        primary key,
    col_order_id     varchar(64) null,
    col_creator      varchar(64) null,
    col_created_time datetime    null
)
    collate = utf8_bin;
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1001', 'd1001', '张三', '2022-07-15 16:43:54');
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1002', 'd1001', '李四', '2022-07-16 16:44:51');
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1003', 'd1001', '王五', '2022-07-17 16:45:42');
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1004', 'd1002', '诸葛', '2022-07-18 16:43:54');
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1005', 'd1002', '赵云', '2022-07-16 16:44:51');
INSERT INTO allowpublickeyretrieval.tbl_a (col_id, col_order_id, col_creator, col_created_time) VALUES ('1006', 'd1002', '曹操', '2022-07-17 16:45:42');
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
listagg函数本身并不具备去重的功能。然而,通过一些技巧,我们可以实现listagg函数的结果去重。以下是三种常用的方法: 方法一:使用DISTINCT关键字 在listagg函数中,我们可以使用DISTINCT关键字来排除重复的值。例如,在使用listagg函数时,可以将查询结果加上DISTINCT关键字,这样就能保证聚合的结果没有重复值。 方法二:使用子查询去重 另一种方法是使用子查询去重。首先,使用子查询获取去重后的值,然后再将结果传递给listagg函数进行聚合。这样可以确保聚合的结果中没有重复值。 方法三:使用ROW_NUMBER函数 最后一种方法是使用ROW_NUMBER函数。我们可以在查询结果中添加ROW_NUMBER函数,并通过分析ROW_NUMBER的值来选择唯一的值。然后,将筛选后的结果传递给listagg函数进行聚合。 总结起来,要实现listagg函数的结果去重,可以使用DISTINCT关键字、子查询去重或者ROW_NUMBER函数。这些方法都可以有效地避免在聚合结果中出现重复的值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Oracle listagg去重distinct三种方法总结](https://blog.csdn.net/Weixiaohuai/article/details/84998212)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值