具有多个联接的资料​​查询

时间:2018-07-05 06:42:36

标签: sql sql-server tsql string-aggregation

SELECT 
    S.enroll_no, 
    Pm.periodname 
FROM
    studentattendencedetails AS SA 
LEFT JOIN 
    studentattendencemaster AS SM ON SA.attendencemasterid = SM.id 
LEFT JOIN 
    tbl_periodmaster AS Pm ON SA.periodid = Pm.id 
LEFT JOIN 
    students AS S ON SA.studentid = S.id 
WHERE  
    SA.isabsent = 2 
    AND s.enroll_no IN ('YYYYYYYYY','XXXXXXXXXX')
ORDER BY 
    S.enroll_no

输出:

Enroll_No   PeriodName 
-----------------------
YYYYYYYYY   1
YYYYYYYYY   2
XXXXXXXXXX  6
XXXXXXXXXX  1
XXXXXXXXXX  7

我想用逗号分隔的值来显示期间名称

Enroll_No   PeriodName
------------------------
YYYYYYYYY   1,2
XXXXXXXXXX  1,6,7

然后我尝试了以下内容查询

SELECT 
    t.enroll_no, 
    periodList  = STUFF((SELECT ', ' + Pm.periodname 
                         FROM studentattendencedetails AS SA 
                         LEFT JOIN studentattendencemaster AS SM ON SA.attendencemasterid = SM.id 
                         LEFT JOIN tbl_periodmaster AS Pm ON SA.periodid = Pm.id 
                         LEFT JOIN students AS S ON SA.studentid = S.id 
                         WHERE s.enroll_no IN ('YYYYYYYYY','XXXXXXXXXX') 
                           AND SA.isabsent = 2
                         FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '')
FROM 
    dbo.students AS t 
WHERE   
    t.enroll_no IN ('YYYYYYYYY','XXXXXXXXXX')
ORDER BY 
    t.enroll_no;

输出:

Enroll_No   PeriodName
---------------------------
YYYYYYYYY   6, 1, 2, 1, 7
XXXXXXXXXX  6, 1, 2, 1, 7

3 个答案:

答案 0 :(得分:1)

如果您正在使用MSSQL 2017,这应该会有所帮助:

    SELECT S.enroll_no, STRING_AGG(Pm.periodname, ',') WITHIN GROUP (ORDER BY Pm.periodname)         
    FROM studentattendencedetails AS SA 
    LEFT JOIN studentattendencemaster AS SM ON SA.attendencemasterid = SM.id 
    LEFT JOIN tbl_periodmaster AS Pm ON SA.periodid = Pm.id 
    LEFT JOIN students AS S ON SA.studentid = S.id 
    WHERE SA.isabsent = 2 and s.enroll_no in ('YYYYYYYYY','XXXXXXXXXX') 
    GROUP BY S.enroll_no
    ORDER BY S.enroll_no

答案 1 :(得分:1)

您需要这样做:

  

所以基本上您错过了一个t.Enroll_no = s.Enroll_no的地方,然后是一个   在您自己的查询中进行分组

declare @table table (enroll nvarchar(50),periodname int)

insert into @table

values


('YYYYYYYYY' , 1),
('YYYYYYYYY' , 2),
('XXXXXXXXXX', 6),
('XXXXXXXXXX',1 ),
('XXXXXXXXXX',7 )

select enroll, PeriodList = stuff((select N', '+cast(PeriodName as nvarchar(2)) from @table t2 where t.enroll = t2.enroll order by periodname 
FOR XML PATH (N''),TYPE).value(N' .[1]', N'nvarchar(max)'),1,2,N'') from @table t
group by enroll

根据主题所有者的评论更新

您可以创建视图:

Create view dbo.EnrollmentPeriodList as 

SELECT 
    S.enroll_no, 
    Pm.periodname 
FROM
    studentattendencedetails AS SA 
LEFT JOIN 
    studentattendencemaster AS SM ON SA.attendencemasterid = SM.id 
LEFT JOIN 
    tbl_periodmaster AS Pm ON SA.periodid = Pm.id 
LEFT JOIN 
    students AS S ON SA.studentid = S.id 
WHERE  
    SA.isabsent = 2 
    AND s.enroll_no IN ('YYYYYYYYY','XXXXXXXXXX') 

然后是代码

select enroll, PeriodList = stuff((select N', '+cast(PeriodName as nvarchar(2)) from dbo.EnrollmentPeriodList t2 where t.enroll = t2.enroll order by periodname 
FOR XML PATH (N''),TYPE).value(N' .[1]', N'nvarchar(max)'),1,2,N'') from dbo.EnrollmentPeriodList t
group by enroll

答案 2 :(得分:0)

您非常亲密。您只需要在子查询中使用一个关联子句:

SELECT s.enroll_no, 
       STUFF((SELECT ', ' + Pm.periodname 
              FROM studentattendencedetails SA JOIN
                   studentattendencemaster SM
                   ON SA.attendencemasterid = SM.id JOIN
                   tbl_periodmaster Pm
                   ON SA.periodid = Pm.id 
              WHERE SA.studentid = S.id AND
                    s.enroll_no IN ('YYYYYYYYY', 'XXXXXXXXXX') AND
                    SA.isabsent = 2
              FOR XML PATH(''), TYPE
             ).value('.[1]', 'nvarchar(max)'), 1, 2, ''
            ) as periodlist
FROM  dbo.students s
WHERE s.enroll_no IN ('YYYYYYYYY','XXXXXXXXXX')
ORDER BY s.enroll_no;