如何连接 PostgreSQL 中字符串字段的字符串“group by” 询问?
我正在寻找一种通过查询连接组内字段字符串的方法。 例如,我有一个表:
ID | COMPANY_ID | EMPLOYEE |
---|---|---|
1 | 1 | Anna |
2 | 1 | Bill |
3 | 2 | Carol |
4 | 2 | Dave |
,我想按 company_id 进行分组以获得类似:
COMPANY_ID | EMPLOYEE |
---|---|
1 | Anna, Bill |
2 | Carol, Dave |
有一个内置的-in mySQL 中的函数来执行此操作 group_concat
I am looking for a way to concatenate the strings of a field within a group by query. So for example, I have a table:
ID | COMPANY_ID | EMPLOYEE |
---|---|---|
1 | 1 | Anna |
2 | 1 | Bill |
3 | 2 | Carol |
4 | 2 | Dave |
and I wanted to group by company_id to get something like:
COMPANY_ID | EMPLOYEE |
---|---|
1 | Anna, Bill |
2 | Carol, Dave |
There is a built-in function in mySQL to do this group_concat
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
我正在使用 Jetbrains Rider,从上面的示例中复制结果来重新执行是一件很麻烦的事情,因为它似乎将所有内容都包装在 JSON 中。 这将它们连接成一个更容易运行的语句
I'm using Jetbrains Rider and it was a hassle copying the results from above examples to re-execute because it seemed to wrap it all in JSON. This joins them into a single statement that was easier to run
您还可以使用格式化功能。 它还可以自行隐式处理 text、int 等类型转换。
You can also use format function. Which can also implicitly take care of type conversion of text, int, etc by itself.
根据 PostgreSQL 9.0 及以上版本,您可以使用名为 string_agg 的聚合函数。 您的新 SQL 应该如下所示:
According to version PostgreSQL 9.0 and above you can use the aggregate function called string_agg. Your new SQL should look something like this:
如果您使用的是不支持 string_agg 的 Amazon Redshift,请尝试使用 listagg。
If you are on Amazon Redshift, where string_agg is not supported, try using listagg.
我发现这个 PostgreSQL 文档很有帮助: http://www.postgresql.org /docs/8.0/interactive/functions-conditional.html。
就我而言,如果字段不为空,我会寻求简单的 SQL 来连接一个带有括号的字段。
I found this PostgreSQL documentation helpful: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html.
In my case, I sought plain SQL to concatenate a field with brackets around it, if the field is not empty.
对PostgreSQL<使用
STRING_AGG
函数/a> 和 Google BigQuery SQL :Use
STRING_AGG
function for PostgreSQL and Google BigQuery SQL:再次关注字符串连接的自定义聚合函数的使用:您需要记住 select 语句将以任何顺序放置行,因此您需要在 select 中执行子操作>from 语句带有 order by 子句,然后是外部 select 带有 group by 子句来聚合字符串,因此:
Following yet again on the use of a custom aggregate function of string concatenation: you need to remember that the select statement will place rows in any order, so you will need to do a sub select in the from statement with an order by clause, and then an outer select with a group by clause to aggregate the strings, thus:
遵循 Kev 的答案,使用 Postgres 文档:
首先,创建一个元素数组,然后使用内置的
array_to_string
函数。Following up on Kev's answer, using the Postgres docs:
First, create an array of the elements, then use the built-in
array_to_string
function.如果您要升级到 8.4,您可能会对这个最新的公告列表片段感兴趣:
我会链接到 8.4 开发文档,但他们似乎还没有列出此功能。
This latest announcement list snippet might be of interest if you'll be upgrading to 8.4:
I'd link to the 8.4 development docs but they don't seem to list this feature yet.
正如已经提到的,创建自己的聚合函数是正确的做法。 这是我的串联聚合函数(您可以找到法语详细信息):)
;
然后将其用作:
As already mentioned, creating your own aggregate function is the right thing to do. Here is my concatenation aggregate function (you can find details in French):
);
And then use it as:
我不承认这个答案,因为我在一番搜索后找到了它:
我不知道的是 PostgreSQL 允许您使用 创建聚合
PostgreSQL 列表中的这篇文章展示了创建一个函数来执行所需操作是多么简单:
I claim no credit for the answer because I found it after some searching:
What I didn't know is that PostgreSQL allows you to define your own aggregate functions with CREATE AGGREGATE
This post on the PostgreSQL list shows how trivial it is to create a function to do what's required:
从 PostgreSQL 9.0 开始,您可以使用名为 string_agg 的聚合函数。 您的新 SQL 应该如下所示:
As from PostgreSQL 9.0 you can use the aggregate function called string_agg. Your new SQL should look something like this:
使用 Postgres 内置数组函数怎么样? 至少在 8.4 上这是开箱即用的:
How about using Postgres built-in array functions? At least on 8.4 this works out of the box:
PostgreSQL 9.0 或更高版本:
现代 Postgres(自 2010 年起)具有
string_agg(expression, delimiter)
函数将完全满足请求者的要求:Postgres 9 还添加了指定
ORDER BY
子句的功能在任何聚合表达式中; 否则,您必须对所有结果进行排序或处理未定义的顺序。 所以你现在可以写:PostgreSQL 8.4.x:
请注意,对 Postgres 8.4 的支持于 2014 年结束,因此您可能应该出于比字符串聚合更重要的原因进行升级。
PostgreSQL 8.4(2009 年)引入了聚合函数
array_agg(expression)
,它收集数组中的值。 然后可以使用 array_to_string() 来给出所需的结果:PostgreSQL 8.3.x 及更早版本:
最初提出这个问题时,没有内置的聚合函数来连接字符串。 最简单的自定义实现(Vajda Gabo 在此邮件列表帖子中建议 等)是使用内置的
textcat
函数:这里是
CREATE AGGREGATE
文档。这只是将所有字符串粘合在一起,没有分隔符。 为了在它们之间插入一个“,”而不在末尾插入“,”,您可能需要创建自己的串联函数并将其替换为上面的“textcat”。 这是我放在一起并在 8.3.12 上测试的一个:
即使该行中的值为 null 或空,此版本也会输出逗号,因此您会得到如下输出:
如果您希望删除额外的逗号来输出此内容:
然后向该函数添加一个
ELSIF
检查,如下所示:PostgreSQL 9.0 or later:
Modern Postgres (since 2010) has the
string_agg(expression, delimiter)
function which will do exactly what the asker was looking for:Postgres 9 also added the ability to specify an
ORDER BY
clause in any aggregate expression; otherwise you have to order all your results or deal with an undefined order. So you can now write:PostgreSQL 8.4.x:
Please note that support for Postgres 8.4 ended in 2014, so you should probably upgrade for more important reasons than string aggregation.
PostgreSQL 8.4 (in 2009) introduced the aggregate function
array_agg(expression)
which collects the values in an array. Thenarray_to_string()
can be used to give the desired result:PostgreSQL 8.3.x and older:
When this question was originally posed, there was no built-in aggregate function to concatenate strings. The simplest custom implementation (suggested by Vajda Gabo in this mailing list post, among many others) is to use the built-in
textcat
function:Here is the
CREATE AGGREGATE
documentation.This simply glues all the strings together, with no separator. In order to get a ", " inserted in between them without having it at the end, you might want to make your own concatenation function and substitute it for the "textcat" above. Here is one I put together and tested on 8.3.12:
This version will output a comma even if the value in the row is null or empty, so you get output like this:
If you would prefer to remove extra commas to output this:
Then add an
ELSIF
check to the function like this: