我有 2 张桌子:
Table A
(ID, Name
) 和 Table B
(Location, Listofpeople
)。
listofpeople
是以下格式的字符串:
"ID1,ID2,ID3,ID4"
我想编写一个 SQL 查询,结果中包含以下列:
Location | Listofpeoplenames
---------|------------------------
Location | Name1,Name2,Name3,Name4
在向您展示如何获得您想要的结果之前,我想声明一下,尽管这为您提供了您所问问题的答案,但它不是您需要的答案。在数据中存储分隔结果是一个“非常”坏主意。您需要询问如何实现这一点的事实表明,如果您使用标准化设计,这个问题将很容易解决;这只是一个JOIN
:
SELECT P.PersonName,
L.LocationName
FROM dbo.Person P
JOIN dbo.Location ON P.LocationID = L.LocationID;
还要注意,该人的位置是针对“人”而不是位置存储的(因为我假设一个人只能有一个位置)。如果一个人可以有很多位置,那么你实际上需要3张桌子;
Person
、Location
和
PersonLocation
,查询看起来更像这样:SELECT P.PersonName,
L.LocationName
FROM dbo.Person P
JOIN dbo.PersonLocation ON P.PersonID = PL.PersonID
JOIN dbo.Location L ON PL.LocationID = L.LocationID;
不幸的是,如上所述,你的设计很糟糕;花点时间修复它。
使用您目前拥有的数据,为了获得您想要的(非标准化)结果,您需要使用
STRING_SPLIT
对数据进行标准化,然后使用
STRING_AGG
再次对其进行非标准化。幸运的是,两者都可以在完全支持的 SQL Server 版本中使用(您不必声明您没有使用不受支持的版本)。如果您无权访问这些函数,则需要使用用户定义的字符串拆分器(例如
DelimitedSplit8K_LEAD
)和/或“旧”FOR XML PATH
(和 STUFF
)方法分别(搜索也会为您带来丰富的结果)。
SELECT L.LocationName,
STRING_AGG(P.PersonName) AS PeopleNames
FROM dbo.Location L
CROSS APPLY STRING_SPLIT(L.PeopleIDs,',') SS
JOIN dbo.People P ON SS.value = P.PersonID
GROUP BY L.LocationName;
不过,我再次建议你修改你的设计。