我需要在两个表之间联接的SQL Server的多行数据中分别串联两列。
例如,我有一个“关联”表和“市场”表,如下所示”
Association:
user_id | role_id | market_id
-------------------------------
1 | a | 1
1 | a | 2
2 | c | 3
2 | c | 4
2 | c | 5
Market:
market_id | market_name
-----------------------
1 | Arizona
2 | Utah
3 | Indiana
4 | Illinois
5 | Kentucky
我需要将Association表中的market_id与每个用户ID合并为一个值,并从Market表中引入合并后的市场名称,并且期望的输出如下所示:
user_id | role_id | market_ids | market_names
--------------------------------------------------
1 | a | 1,2 | Arizona,Utah
2 | c | 3,4,5 | Indiana,Illinois,Kentucky
现在,我能够使用以下SQL成功连接市场ID,但仍然可以为每个市场获得多行数据:
SELECT DISTINCT
a.user_id,
a.role_id,
SUBSTRING(
(
SELECT DISTINCT ', ' + market_id AS [text()]
FROM Association aa
WHERE a.user_id = aa.user_id
FOR XML PATH ('')
), 2, 1000) [market_ids],
SUBSTRING(
(
SELECT DISTINCT ', ' + market_name AS [text()]
FROM Market bb
WHERE a.market_id = bb.market_id
FOR XML PATH ('')
), 2, 1000) [Market Name]
FROM
Association a
INNER JOIN
Market b
ON a.market_id = d.market_id
关于如何实现第二级连接的任何想法?
答案 0 :(得分:2)
具有Row_Number()来保持演示顺序的CTE应该可以解决问题
示例
;with cte as (
Select A.*
,B.Market_Name
,RN = Row_Number() over (Partition By user_id,role_id order by a.market_id)
From Association A
Join Market B on A.market_id=B.market_id
)
Select Distinct
user_id
,role_id
,market_ids = stuff((Select concat(',',market_id ) From cte Where user_id=A.user_id and role_id=A.role_id Order By RN For XML Path ('')),1,1,'')
,market_names = stuff((Select concat(',',market_name) From cte Where user_id=A.user_id and role_id=A.role_id Order By RN For XML Path ('')),1,1,'')
From cte A
返回
user_id role_id market_ids market_names
1 a 1,2 Arizona,Utah
2 c 3,4,5 Indiana,Illinois,Kentucky
答案 1 :(得分:0)
与Stuff()
相比,我更喜欢使用Substring()
。无论如何,基本上对于市场名称,您应该在您的子查询中进行关联联接,然后在用户ID上联接两个关联表。尝试这样的事情:
SELECT DISTINCT
a.user_id,
a.role_id,
STUFF(
(
SELECT DISTINCT ', ' + cast(market_id as varchar(25))
FROM Association aa
WHERE a.[user_id] = aa.[user_id]
FOR XML PATH ('')
), 1, 1,'') [market_ids],
STUFF(
(
SELECT DISTINCT ', ' + market_name
FROM Market bb
Inner join Association aaa on aaa.market_id = bb.market_id
WHERE a.user_id = aaa.user_id
FOR XML PATH ('')
), 1, 1,'') [Market Name]
FROM Association a
您的原始查询可以写为:
SELECT DISTINCT
a.[user_id],
a.role_id,
SUBSTRING(
(
SELECT DISTINCT ', ' + cast(market_id as varchar(25)) AS [text()]
FROM #Association aa
WHERE a.[user_id] = aa.[user_id]
FOR XML PATH ('')
), 2, 1000) [market_ids],
SUBSTRING(
(
SELECT DISTINCT ', ' + market_name AS [text()]
FROM #Market bb
INNER JOIN #Association aaa on aaa.market_id = bb.market_id
WHERE a.user_id = aaa.user_id
FOR XML PATH ('')
), 2, 1000) [Market Name]
FROM #Association a