如何在 SQL Server 中使用 GROUP BY 连接字符串?
我怎么
id Name Value
1 A 4
1 B 8
2 C 9
去
id Column
1 A:4, B:8
2 C:9
How do I get:
id Name Value
1 A 4
1 B 8
2 C 9
to
id Column
1 A:4, B:8
2 C:9
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
我使用了这种方法,可能更容易掌握。 获取根元素,然后连接到选择具有相同 ID 但不是“官方”名称的任何项目
I used this approach which may be easier to grasp. Get a root element, then concat to choices any item with the same ID but not the 'official' name
您好,现在可以使用 STRING_AGG 函数将字符串连接到 SQL Server 的 group by 中。
这里是一个例子
---创建表
--插入
--请求
--结果
Hello it is now possible to concatenate string in group by with SQL Server, by using STRING_AGG function.
Here an example
--- Create table
-- Insert
--Request
--Result
无需 CURSOR、WHILE 循环或用户定义函数。
只需要创造性地使用 FOR XML 和 PATH。
[注意:此解决方案仅适用于 SQL 2005 及更高版本。 原始问题没有指定正在使用的版本。]
No CURSOR, WHILE loop, or User-Defined Function needed.
Just need to be creative with FOR XML and PATH.
[Note: This solution only works on SQL 2005 and later. Original question didn't specify the version in use.]
如果是 SQL Server 2017 或 SQL Server Vnext、SQL Azure,您可以使用
STRING_AGG
,如下所示:If it is SQL Server 2017 or SQL Server Vnext, SQL Azure you can use
STRING_AGG
as below:我已经看到使用 FOR XML PATH 的建议,但是使用 XML 路径不会像您所期望的那样完美连接......它将替换“&” 与“&” 并且还会与
<
和>
混淆...也许还有其他一些事情,不确定...但您可以尝试这个:
我遇到了一个解决方法...您需要将:替换
为:
...或
NVARCHAR(MAX) 如果这就是您使用的。
我想知道为什么
SQL
没有连接聚合函数? 这是一个尴尬的解决方案...更新:SQL Server 2017 中似乎添加了聚合函数,因此除非您使用旧版本,否则这个答案已过时。
I have seen suggestions to use FOR XML PATH, but using XML path will not perfectly concatenate as you might expect... it will replace "&" with "&" and will also mess with
<
and>
...maybe a few other things, not sure...but you can try this:
I came across a workaround for this... you need to replace:
with:
...or
NVARCHAR(MAX)
if that's what your using.I wonder why
SQL
doesn't have a concatenate aggregate function? This is an awkward solution...Update: an aggregate function seems to have been added in SQL Server 2017, so this answer is obsolete unless you are using an older version.
当我尝试将 Kevin Fairchild 的建议转换为使用包含空格和特殊 XML 字符(
&
、<
、> 的字符串时,我遇到了一些问题。
)已编码。我的代码的最终版本(它没有回答原来的问题,但可能对某人有用)如下所示:它
不是使用空格作为分隔符并用逗号替换所有空格,而是在前面加上一个逗号并然后使用
STUFF
删除每个值的前两个字符。XML 编码是通过使用 TYPE 指令自动处理的。
I ran into a couple of problems when I tried converting Kevin Fairchild's suggestion to work with strings containing spaces and special XML characters (
&
,<
,>
) which were encoded.The final version of my code (which doesn't answer the original question but may be useful to someone) looks like this:
Rather than using a space as a delimiter and replacing all the spaces with commas, it just pre-pends a comma and space to each value then uses
STUFF
to remove the first two characters.The XML encoding is taken care of automatically by using the TYPE directive.
使用 Sql Server 2005 及更高版本的另一个选项
Another option using Sql Server 2005 and above
八年后... Microsoft SQL Server vNext 数据库引擎终于增强了 Transact-SQL,直接支持分组字符串连接。 社区技术预览版 1.0 添加了 STRING_AGG 函数,CTP 1.1 为 STRING_AGG 函数添加了WITHIN GROUP 子句。
参考:https://msdn.microsoft.com/en-us/library/mt775028 .aspx
Eight years later... Microsoft SQL Server vNext Database Engine has finally enhanced Transact-SQL to directly support grouped string concatenation. The Community Technical Preview version 1.0 added the STRING_AGG function and CTP 1.1 added the WITHIN GROUP clause for the STRING_AGG function.
Reference: https://msdn.microsoft.com/en-us/library/mt775028.aspx
从 http://groupconcat.codeplex.com 安装 SQLCLR 聚合
然后您可以编写这样的代码来获取结果你要求:
Install the SQLCLR Aggregates from http://groupconcat.codeplex.com
Then you can write code like this to get the result you asked for:
SQL Server 2005 及更高版本允许您创建自己的自定义聚合函数,包括诸如串联之类的内容 - 请参阅链接文章底部的示例。
SQL Server 2005 and later allow you to create your own custom aggregate functions, including for things like concatenation- see the sample at the bottom of the linked article.
一个例子是
在 Oracle 中您可以使用 LISTAGG 聚合函数。
原始记录
Sql
结果
An example would be
In Oracle you can use LISTAGG aggregate function.
Original records
Sql
Result in
这只是 Kevin Fairchild 帖子的补充(顺便说一句,非常聪明)。 我会把它添加为评论,但我还没有足够的点:)
我正在使用这个想法来处理我正在处理的视图,但是我连接的项目包含空格。 所以我稍微修改了代码,不使用空格作为分隔符。
再次感谢凯文提供的很酷的解决方法!
This is just an addition to Kevin Fairchild's post (very clever by the way). I would have added it as a comment, but I don't have enough points yet :)
I was using this idea for a view I was working on, however the items I was concatinating contained spaces. So I modified the code slightly to not use spaces as delimiters.
Again thanks for the cool workaround Kevin!
此类问题在这里经常被问到,解决方案将在很大程度上取决于底层需求:
https:// stackoverflow.com/search?q=sql+pivot
和
https://stackoverflow.com/search?q= sql+concatenate
通常,在没有动态 sql、用户定义函数或游标的情况下,没有纯 SQL 的方法可以做到这一点。
This kind of question is asked here very often, and the solution is going to depend a lot on the underlying requirements:
https://stackoverflow.com/search?q=sql+pivot
and
https://stackoverflow.com/search?q=sql+concatenate
Typically, there is no SQL-only way to do this without either dynamic sql, a user-defined function, or a cursor.
补充一下 Cade 所说的,这通常是前端显示的事情,因此应该在那里处理。 我知道有时对于文件导出或其他“仅 SQL”解决方案之类的事情用 SQL 编写 100% 的内容会更容易,但大多数时候这种串联应该在显示层中处理。
Just to add to what Cade said, this is usually a front-end display thing and should therefore be handled there. I know that sometimes it's easier to write something 100% in SQL for things like file export or other "SQL only" solutions, but most of the times this concatenation should be handled in your display layer.
不需要光标... while 循环就足够了。
Don't need a cursor... a while loop is sufficient.
让我们变得非常简单:
将这一行:替换
为您的查询。
Let's get very simple:
Replace this line:
With your query.
如果 group by 主要包含一项,则可以通过以下方式显着提高性能:
You can improve performance significant the following way if group by contains mostly one item:
没有看到任何交叉应用答案,也不需要 xml 提取。 这是凯文·费尔柴尔德 (Kevin Fairchild) 所写内容的略有不同的版本。 在更复杂的查询中使用它更快更容易:
didn't see any cross apply answers, also no need for xml extraction. Here is a slightly different version of what Kevin Fairchild wrote. It's faster and easier to use in more complex queries:
使用 Stuff 和 for xml 路径运算符将行连接到字符串 :Group By 两列 -->
Using the Stuff and for xml path operator to concatenate rows to string :Group By two columns -->
使用替换函数和 FOR JSON PATH
有关示例数据和更多方法 点击此处
Using Replace Function and FOR JSON PATH
For sample data and more ways click here
如果启用了 clr,则可以使用 Group_Concat来自 GitHub 的库
If you have clr enabled you could use the Group_Concat library from GitHub
对于我所有的医护人员:
For all my healthcare folks out there:
另一个没有垃圾的例子: ",TYPE).value('(./text())[1]','VARCHAR(MAX)')"
输入输出是
Another example without the garbage: ",TYPE).value('(./text())[1]','VARCHAR(MAX)')"
Input-output is