Oracle聚合函数LISTAGG和WM_CONCAT简介

目录

Oracle聚合函数LISTAGG和WM_CONCAT简介

在处理数据库中的数据聚合任务时,我们经常需要将多行数据合并成一行字符串或列表。Oracle 提供了两种函数来实现这一目标:LISTAGG 和 WM_CONCAT。这两种函数各有特点,适用于不同的场景。

LISTAGG 函数

LISTAGG 是一个聚合函数,用于将一组值连接成一个字符串。它支持指定分隔符,并且可以设置最大长度以避免结果超出限制。

1.语法

sql 复制代码
LISTAGG(column, separator) WITHIN GROUP (ORDER BY column)
  • column: 要连接的列名。
  • separator: 用作连接值之间的分隔符。
  • WITHIN GROUP (ORDER BY column): 可选子句,用于指定连接结果的顺序。

2.示例

假设我们有一个表 orders,其中包含以下数据:

order_id product
1 Apples
1 Bananas
2 Oranges
2 Apples
2 Oranges

创建表 orders

sql 复制代码
CREATE TABLE orders (
  order_id NUMBER(5) NOT NULL,
  product VARCHAR2(20) NOT NULL
);

插入数据

sql 复制代码
INSERT INTO orders (order_id, product)
VALUES (1, 'Apples');

INSERT INTO orders (order_id, product)
VALUES (1, 'Bananas');

INSERT INTO orders (order_id, product)
VALUES (2, 'Oranges');

INSERT INTO orders (order_id, product)
VALUES (2, 'Apples');

INSERT INTO orders (order_id, product)
VALUES (2, 'Oranges');

使用上面的 orders 表,我们可以使用 LISTAGG 函数来获取每个订单的所有产品:

sql 复制代码
SELECT order_id,
       LISTAGG(product, ', ') WITHIN GROUP (ORDER BY product) AS products
FROM orders
GROUP BY order_id;

输出:

order_id products
1 Apples, Bananas
2 Apples, Oranges, Oranges

3.去除重复值

由于 LISTAGG 不支持 DISTINCT,我们可以通过子查询或者窗口函数来达到去除重复值的目的:

sql 复制代码
SELECT order_id,
       LISTAGG(product, ', ') WITHIN GROUP (ORDER BY product) AS products
FROM (
  SELECT order_id, product
  FROM (
    SELECT order_id, product,
           ROW_NUMBER() OVER (PARTITION BY order_id, product ORDER BY (NULL)) AS rn
    FROM orders
  )
  WHERE rn = 1
)
GROUP BY order_id;

输出:

order_id products
1 Apples, Bananas
2 Apples, Oranges

WM_CONCAT 函数

WM_CONCAT 是另一个连接函数,它将多个值连接成一个字符串。这个函数主要用于连接少量的数据,因为它没有内置的排序功能,并且可能会遇到性能问题。

1.语法

sql 复制代码
WM_CONCAT(column)
  • column: 要连接的列名。

2.示例

使用上面的 orders 表,我们可以使用 WM_CONCAT 函数来获取每个订单的所有产品:

sql 复制代码
SELECT order_id,
       WM_CONCAT(product) AS products
FROM orders
GROUP BY order_id;

输出:

order_id products
1 Apples, Bananas
2 Oranges,Oranges,Apples

备注:使用 WM_CONCAT 函数没有内置的排序功能,结果可能无顺序。

3.去除重复值

在 WM_CONCAT 中去除重复值的方式非常直观,可以直接使用 DISTINCT 关键字:

sql 复制代码
SELECT order_id,
       WM_CONCAT(DISTINCT product) AS products
FROM orders
GROUP BY order_id;

输出:

order_id products
1 Apples, Bananas
2 Apples ,Oranges

比较

1.性能

  • LISTAGG: 性能较好,尤其是在处理大量数据时。
  • WM_CONCAT: 在处理大量数据时性能较差。

2.排序与分隔符

  • LISTAGG: 支持排序和自定义分隔符。
  • WM_CONCAT: 不支持排序,使用逗号作为默认分隔符。

3.去除重复值

  • LISTAGG: 需要通过子查询或窗口函数去除重复值。
  • WM_CONCAT : 可以直接使用 DISTINCT 关键字去除重复值。

LISTAGG 和 WM_CONCAT 都可以用来连接多个值,但 LISTAGG 更加灵活并且性能更优。对于大多数情况来说,推荐使用 LISTAGG 函数,特别是在需要对结果进行排序或需要自定义分隔符的情况下。在仅需要去除重复值时 WM_CONCAT 可能更方便,WM_CONCAT 可以直接使用 DISTINCT 关键字,而 LISTAGG 则需要通过子查询或窗口函数的方法来实现。

相关推荐
白帽攻防录12 小时前
SRC 挖洞:Roundcube 预认证 SQL 注入深度复盘,CVE-2026-48842 preg_replace 转义绕过怎么打穿邮件系统
网络·数据库·sql·网络安全·sql注入
꯭自꯭闭꯭12 小时前
达梦SQL优化相关
linux·运维·数据库·sql
对空六课13 小时前
支持注意力分析的热力图工具有哪些?
前端·数据库·数据分析
南京码讯光电技术有限公司13 小时前
How to Design an Antenna System for an Industrial WiFi Module
数据库·人工智能
lusklusklusk14 小时前
Oracle数据库基础之2_体系结构
数据库·oracle
可乐ea14 小时前
从第一性原理构建 AI Agent:提示词、工具、技能与记忆全解剖
数据库·人工智能·工具调用·ai智能体·提示词工程·agent开发·智能体记忆
东方护航数据恢复(深圳)15 小时前
医疗案例:HIS/PACS 数据库页损坏修复,医院不停诊完成恢复【东方护航数据恢复深圳店】
数据库·数据恢复·医疗·二次开盘
lusklusklusk16 小时前
Oracle数据库基础之11_Duplicate和Dataguard和RAC
数据库·oracle
PHP实战开发录17 小时前
MySQL字段加索引为什么没变快
数据库·mysql·php·开发
红红谈说18 小时前
标签化推送与已读统计怎么做?一次通知链路的工程复盘
数据库·消息推送·数字乡村·集合运算·已读回执·标签体系·写入放大