Sql-Server-2008

在單個結果中連接一對多欄位?

  • September 5, 2019

假設我有以下查詢:

SELECT * 
FROM AppDetails, AppTags 
WHERE AppDetails.AppID = '1' 
 AND AppDetails.AppID = AppTags.AppID

這給出了以下結果:

AppID    AppName        AppType    Tag
1        Application1   Utility    Test1
1        Application1   Utility    Test2
1        Application1   Utility    Test3

如何修改查詢以返回如下內容:

AppID    AppName        AppType    Tags
1        Application1   Utility    Test1,Test2,Test3

不幸的是,SQL Server 沒有執行組連接的單一函式,但有幾種不同的方法可以獲得結果。

您可以實現FOR XML PATHSTUFF()

SELECT DISTINCT d.AppId,
 d.AppName,
 d.AppType,
 Tags = STUFF((SELECT ', ' + t.TagName
               FROM AppTags t
               where d.AppID = t.AppID
               FOR XML PATH (''))
               , 1, 1, '') 
FROM AppDetails d
WHERE d.AppID = '1';

請參閱SQL Fiddle with Demo

或者你可以FOR XML PATH使用CROSS APPLY

SELECT DISTINCT d.AppId,
 d.AppName,
 d.AppType,
 tags = left(t.tags, len(t.tags)-1) 
FROM AppDetails d
CROSS APPLY
(
 SELECT t.TagName + ', '
 FROM AppTags t
 WHERE d.AppID = t.AppID
 FOR XML PATH('')
) t (Tags)
WHERE d.AppID = '1';

請參閱SQL Fiddle with Demo

如果您想查詢這些tags值,那麼您可以使用類似於以下內容的 CTE:

;with cte as
(
 SELECT DISTINCT d.AppId,
   d.AppName,
   d.AppType,
   Tags = STUFF((SELECT ', ' + t.TagName
                 FROM AppTags t
                 where d.AppID = t.AppID
                 FOR XML PATH (''))
                 , 1, 1, '') 
 FROM AppDetails d
 WHERE d.AppID = '1'
)
select *
from cte
where tags like '%test1%'

展示

如果TagName包含某些 XML 字元(例如>, &),它們將被實體化(>-> >, &-> &)。為避免這種情況,請更改FOR XML PATH('')FOR XML PATH, TYPE).value(N'.[1]',N'nvarchar(max)').

引用自:https://dba.stackexchange.com/questions/50153