问题
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
Output:
Enroll_No PeriodName
-----------------------
YYYYYYYYY 1
YYYYYYYYY 2
XXXXXXXXXX 6
XXXXXXXXXX 1
XXXXXXXXXX 7
I would like to display the period name with comma-separated values as follows
Enroll_No PeriodName
------------------------
YYYYYYYYY 1,2
XXXXXXXXXX 1,6,7
And I tried the following stuff query
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;
Output:
Enroll_No PeriodName
---------------------------
YYYYYYYYY 6, 1, 2, 1, 7
XXXXXXXXXX 6, 1, 2, 1, 7
回答1:
If you are working with MSSQL 2017,this should help:
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
回答2:
You need to do like this:
So basically your missing a where t.Enroll_no = s.Enroll_no and then a group by in your own query
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
Update based on topic owners comments
You can create a view:
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')
And then the code
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
回答3:
You are quite close. You just need a correlation clause in your subquery:
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;
来源:https://stackoverflow.com/questions/51184828/stuff-query-with-multiple-joins