具有不同字符的 SQL Server 组连接
Posted
技术标签:
【中文标题】具有不同字符的 SQL Server 组连接【英文标题】:SQL Server Group Concat with Different characters 【发布时间】:2012-11-23 04:50:21 【问题描述】:我查看了许多在 SQL Server 中模拟“组连接”功能的解决方案。虽然我想制作一个更易于阅读的解决方案,但我不知道该怎么做。
我有一个看法:
ParentID | ChildName
其中包含记录,例如:
1 | Max
1 | Jessie
2 | Steven
2 | Lucy
2 | Jake
3 | Mark
我想“分组 Concat”这些以获得:
1 | Max and Jessie
2 | Steven, Lucy and Jake
3 | Mark
因此,如果只有 1 个孩子,则返回名称,如果有多个,则将最后 2 个用 ' 和 ' 连接,其他所有用 ', ' 连接。
在不求助于 CLR 的情况下如何做到这一点,我有点坚持,我不想这样做。我对函数很满意 - 但速度是个问题,我如何确定子编号以便我可以在 ' 和 '、'、' 或 '' 之间进行选择?
【问题讨论】:
+1 个有趣的问题。您不想按父母对孩子的数量进行分组,而是想知道他们的名字显示和连接。 :) 【参考方案1】:制作更易读的解决方案
对不起,这是我能满足你的要求的最好办法了。
SQL Fiddle
MS SQL Server 2008 架构设置:
create table YourTable
(
ParentID int,
ChildName varchar(10)
);
insert into YourTable values
(1, 'Max'),
(1, 'Jessie'),
(2, 'Steven'),
(2, 'Lucy'),
(2, 'Jake'),
(3, 'Mark');
查询 1:
with T as
(
select ParentID,
ChildName,
row_number() over(partition by ParentID order by ChildName) as rn,
count(*) over(partition by ParentID) as cc
from YourTable
)
select T1.ParentID,
(
select case
when T2.rn = 1 and T2.cc > 1 then ' and '
else ', '
end + T2.ChildName
from T as T2
where T1.ParentID = T2.ParentID
order by T2.rn desc
for xml path(''), type
).value('substring(text()[1], 3)', 'varchar(max)') as ChildNames
from T as T1
group by T1.ParentID
Results:
| PARENTID | CHILDNAMES |
------------------------------------
| 1 | Max and Jessie |
| 2 | Steven, Lucy and Jake |
| 3 | Mark |
【讨论】:
@techdo 谢谢,我 +1 你的答案,因为它是唯一真正给出正确输出的其他答案。哪个答案更易于阅读......好吧,这是一个近距离的电话:)。 谢谢米凯尔。在我不完整的答案之后我离开了。很高兴看到你的这个:) 感谢 Mikael,这太棒了。我的解决方案远没有这么好。非常感谢,抱歉回复晚了,一直在出差。干杯。【参考方案2】:select ParentID,STUFF((SELECT ' and '+ChildName
FROM Table1 where ParentID=a.ParentID
FOR XML PATH('')),1,4,'') as cnmae from Table1 a
group by ParentID
SQL FIDDLE DEMO
【讨论】:
AnandPhadke,我看不出你的答案和我的有太大区别。但我被否决了哈哈哈 ;)【参考方案3】:很好的逻辑问题。请检查下面的查询(有点冗长,但无法阻止自己发布我的小逻辑:))。
CREATE TABLE #SampleTable ([ParentID] int, [ChildName] varchar(6));
INSERT INTO #SampleTable VALUES (1, 'Max')
INSERT INTO #SampleTable VALUES (1, 'Jessie')
INSERT INTO #SampleTable VALUES (2, 'Steven')
INSERT INTO #SampleTable VALUES (2, 'Lucy')
INSERT INTO #SampleTable VALUES (2, 'Jake')
INSERT INTO #SampleTable VALUES (3, 'Mark')
select * From #SampleTable
;WITH T(xParentID, xChildName, xChildNameResult, xC1, xC2)AS
(
SELECT * FROM(
SELECT
ParentID ,
ChildName,
CAST(ChildName AS NVARCHAR(MAX)) AS ChildNameResult,
ROW_NUMBER() OVER (PARTITION BY [ParentID] ORDER BY ChildName) C1,
COUNT(*) OVER (PARTITION BY [ParentID]) C2
FROM #SampleTable)x WHERE x.C1=1
UNION ALL
SELECT ParentID, ChildName,
CAST(T.xChildNameResult+(CASE WHEN C1=1 THEN '' WHEN C1=C2 THEN ' and ' ELSE ', ' END)+ChildName AS NVARCHAR(MAX)), C1, C2
FROM
(
SELECT
ParentID ,
ChildName,
ROW_NUMBER() OVER (PARTITION BY ParentID order by ChildName) C1,
COUNT(*) OVER (PARTITION BY ParentID) C2
FROM #SampleTable
)y INNER JOIN T ON y.ParentID=T.xParentID and y.c1=T.xC1+1
)SELECT xParentID, xChildNameResult FROM T where xC1=xC2
OPTION (MAXRECURSION 0);
【讨论】:
以上是关于具有不同字符的 SQL Server 组连接的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL Server 中连接字符串,并按不同的列排序/排序?
应用程序意图= readonly SQL Server连接错误
SQL Server 2017 AlwaysOn AG 自动初始化