SQL 中的 STUFF 等效函数(MySQL 中的 GROUP_CONCAT / Oracle 中的 LISTAGG)

Posted

技术标签:

【中文标题】SQL 中的 STUFF 等效函数(MySQL 中的 GROUP_CONCAT / Oracle 中的 LISTAGG)【英文标题】:Equivalent function to STUFF in SQL (GROUP_CONCAT in MySSQL / LISTAGG in Oracle) 【发布时间】:2014-12-25 11:00:08 【问题描述】:

有谁知道Firebird 2.5是否有类似于SQL中的“STUFF”函数的功能?

我有一个包含父用户记录的表,以及另一个包含与父用户相关的子用户记录的表。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而无需使用第二个查询,循环遍历给定 ID 返回的值并自己创建字符串。

我搜索了任何其他相关问题,但没有找到任何问题。 此链接string equivalent of Sum to concatenate 中的问题基本上也是我想做的,但是使用 Firebird 2.5 数据库。

【问题讨论】:

【参考方案1】:

看起来你很幸运 - Firebird 2.1 引入了 LIST() aggregate function,它的工作方式类似于 mysql 中的 GROUP_CONCAT,它允许这样的查询:

SELECT p.Name, LIST(c.Name, ', ')
FROM parent p INNER JOIN child c on c.parentid = p.parentid
GROUP by p.Name;

编辑、重新排序

在应用 LIST 聚合函数之前,您可以通过对派生表中的数据进行预排序来影响排序,如下所示:

SELECT x.ParentName, LIST(x.ChildName, ', ')
FROM 
(
  SELECT p.Name as ParentName, c.Name as ChildName
  FROM parent p INNER JOIN child c on c.parentid = p.parentid
  ORDER BY c.Name DESC
) x
GROUP by x.ParentName;

【讨论】:

订购怎么样?假设我需要按字母顺序排列父母和孩子的姓名,如果我添加“ORDER BY p.Name, c.Name”,我会收到此错误:“ORDER BY 子句中的表达式无效(不包含在聚合函数或GROUP BY 子句)",因为 order by 子句中存在 c.Name。有没有办法解决这个问题? @Bozzy 您可以通过在派生表中进行有序预投影来影响排序。我已经更新了答案。

以上是关于SQL 中的 STUFF 等效函数(MySQL 中的 GROUP_CONCAT / Oracle 中的 LISTAGG)的主要内容,如果未能解决你的问题,请参考以下文章

sql stuff函数的语法和作用

CROSS APPLY VS STUFF 函数

实体框架核心中等效的 SQL RIGHT 函数

C# 等效于 SQL Server 中的 IsNull() 函数

SQL 中STUFF函数用法

是否有与 SQL Server NewId() 函数等效的 Access?