LISTAGG
将多行中的值连接为一个字符串,并使用指定的分隔符分隔。此操作可以通过两种不同的函数类型执行:
- 聚合函数:连接会在整个结果集的所有行上进行。
- 窗口函数:连接会在结果集的每个分区内进行,分区由
PARTITION BY子句定义。
语法
-- Aggregate Function
LISTAGG([DISTINCT] <expr> [, <delimiter>])
[WITHIN GROUP (ORDER BY <order_by_expr>)]
-- Window Function
LISTAGG([DISTINCT] <expr> [, <delimiter>])
[WITHIN GROUP (ORDER BY <order_by_expr>)]
OVER ([PARTITION BY <partition_expr>])
别名
返回类型
字符串。
示例
在此示例中,我们有一张客户订单表。每个订单都属于某个客户,我们希望创建一个列表,列出每个客户购买过的所有产品。
CREATE TABLE orders (
customer_id INT,
product_name VARCHAR
);
INSERT INTO orders (customer_id, product_name) VALUES
(1, 'Laptop'),
(1, 'Mouse'),
(1, 'Laptop'),
(2, 'Phone'),
(2, 'Headphones');
以下示例将 LISTAGG 用作聚合函数,并结合 GROUP BY 将每个客户购买的所有产品连接为一个字符串:
SELECT
customer_id,
LISTAGG(product_name, ', ') WITHIN GROUP (ORDER BY product_name) AS product_list
FROM orders
GROUP BY customer_id;
┌─────────────────────────────────────────┐
│ customer_id │ product_list │
├─────────────────┼───────────────────────┤
│ 2 │ Headphones, Phone │
│ 1 │ Laptop, Laptop, Mouse │
└─────────────────────────────────────────┘
以下示例将 LISTAGG 用作窗口函数,因此每一行都会保留其原始明细,同时还会显示该客户分组的完整产品列表:
SELECT
customer_id,
product_name,
LISTAGG(product_name, ', ') WITHIN GROUP (ORDER BY product_name)
OVER (PARTITION BY customer_id) AS product_list
FROM orders;
┌────────────────────────────────────────────────────────────┐
│ customer_id │ product_name │ product_list │
├─────────────────┼──────────────────┼───────────────────────┤
│ 2 │ Phone │ Headphones, Phone │
│ 2 │ Headphones │ Headphones, Phone │
│ 1 │ Laptop │ Laptop, Laptop, Mouse │
│ 1 │ Mouse │ Laptop, Laptop, Mouse │
│ 1 │ Laptop │ Laptop, Laptop, Mouse │
└────────────────────────────────────────────────────────────┘