[SQL Server 2014中涉及多个表联接时如何在逗号分隔列表中显示行数据

问题描述 投票:0回答:2

我想用逗号分隔的列表显示特定ID的多行数据。如果它只有一个联接,那么我可以毫无问题地显示,但是当它包含许多表时,将无法正确显示。

我的数据如下。

Declare @EmpClass Table(ClassId varchar(10),EmpId int)
INSERT INTO @EmpClass
Values('A',1)
,('B',2)
,('C',3)

Declare @Employees Table (EmpId int, EmpName Varchar(100))
INSERT INTO @Employees
VALUES(1,'RAM')
,(2,'RAJ')
,(3,'LAXMAN')

Declare @EmpSubjects Table (EmpId int, SubjectId int)
INSERT INTO @EmpSubjects 
VALUES(1,1)
,(1,2)
,(1,3)
,(2,1)
,(3,1)
,(3,2)

    Declare @Subjects Table (SubjectId int, Subject Varchar(100))
    INSERT INTO @Subjects
    VALUES(1,'Maths')
    ,(2,'Science')
    ,(3,'Physics')
    ,(4,'Physics')
    ,(5,'Maths')
    ,(6,'Physics')

我尝试了以下代码并获得了以下结果

SELECT EC.ClassId,E.EmpId
    ,ES.SubjectId,Subject
FROM @EmpClass EC
LEFT JOIN @Employees E ON EC.EmpId=E.EmpId
LEFT JOIN @EmpSubjects ES ON E.EmpId=ES.EmpId
LEFT JOIN @Subjects S ON S.SubjectId=ES.SubjectId
WHERE E.EmpId=1

我得到以下结果

ClassId EmpId   SubjectId   Subject
A         1       1         Maths
A         1       2         Science
A         1       3         Physics

结果需要如下。

ClassId   EmpId SubjectId    Subject
A           1       1         {"1":"Maths","2":"Science","3":"Physics"}

感谢您对此的帮助。

谢谢

sql-server tsql
2个回答
0
投票

您期望的结果中用逗号分隔的数据对我来说就像JSON。您是否尝试过类似的方法?

SELECT EC.ClassId,E.EmpId,
    Subject = (
        SELECT [1], [2], [3], [4], [5], [6]
        FROM (
            SELECT S.SubjectID, S.Subject
            FROM @EmpSubjects ES
            LEFT JOIN @Subjects S ON S.SubjectId=ES.SubjectId
            WHERE ES.EmpId=E.EmpId
        ) as Src
        PIVOT (
            MAX([Subject])
            for [SubjectID] in ([1], [2], [3], [4], [5], [6])
        ) as p
        FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER
    )
FROM @EmpClass EC
LEFT JOIN @Employees E ON EC.EmpId=E.EmpId
WHERE E.EmpId=1

产生哪个结果:

ClassId  EmpId  Subject
-------- ------ -----------------------------------------
A        1      {"1":"Maths","2":"Science","3":"Physics"}

0
投票

在2014年,这会带来更多挑战,但这是使用xml函数的一个选项:

SELECT  [Results].[ClassId]
       , [Results].[EmpId]
       , '{' + STUFF((SELECT ',"' + CONVERT(VARCHAR(2), tb.[SubjectId]) + '":"' + CAST(tb.[Subject] AS VARCHAR(MAX)) + '"'
                   FROM   (
                              SELECT    [EC].[ClassId]
                                      , [E].[EmpId]
                                      , [ES].[SubjectId]
                                      , [S].[Subject]
                              FROM      @EmpClass [EC]
                              LEFT JOIN @Employees [E]
                                  ON [EC].[EmpId] = [E].[EmpId]
                              LEFT JOIN @EmpSubjects [ES]
                                  ON [E].[EmpId] = [ES].[EmpId]
                              LEFT JOIN @Subjects [S]
                                  ON [S].[SubjectId] = [ES].[SubjectId]
                          ) AS [tb]
                   WHERE  ( [tb].[ClassId] = [Results].[ClassId] AND tb.[EmpId] = [Results].[EmpId] )
                   FOR XML PATH(''), TYPE
               ).[value]('(./text())[1]', 'VARCHAR(MAX)'), 1, 1, '') + '}' AS [Subjects]
FROM     (
             SELECT    [EC].[ClassId]
                     , [E].[EmpId]
                     , [ES].[SubjectId]
             FROM      @EmpClass [EC]
             LEFT JOIN @Employees [E]
                 ON [EC].[EmpId] = [E].[EmpId]
             LEFT JOIN @EmpSubjects [ES]
                 ON [E].[EmpId] = [ES].[EmpId]
         ) [Results]
WHERE     [Results].[EmpId] = 1
GROUP BY [Results].[ClassId], [Results].[EmpId]

为您提供结果:

ClassId    EmpId       Subjects
---------- ----------- -------------------------------------------
A          1           {"1":"Maths", "2":"Science", "3":"Physics"}

第一个子查询正在使用FOR XML转换为XML,因此我们基本上可以聚合列。然后STUFF()从中删除前导“,”。然后用“ {}”

包装
© www.soinside.com 2019 - 2024. All rights reserved.