这具有填充类表和studentID和classID之间的连接表的查询......
(注意:首先运行注释掉的逻辑来填充临时表)
/*
Create Table testData (StudentID Int, [Subject] Int, Section Varchar(2))
Insert testData
Select 1,2,'AM'
Union All
Select 1,3,'AM'
Union All
Select 1,1,'AM'
Union All
Select 2,2,'AM'
Union All
Select 2,3,'AM'
Union All
Select 2,1,'AM'
Union All
Select 3,4,'AM'
Union All
Select 3,2,'PM'
Union All
Select 3,3,'PM'
Union All
Select 4,2,'PM'
Union All
Select 4,3,'PM';
*/
-- Get class info
If Object_ID('tempdb..#classes') Is Not Null Drop Table #classes;
With studentClasses As
(
Select t.StudentID,
Replace(( Select Convert(Varchar(10),[Subject])+'_'+Section As 'data()'
From #testData t2
Where t.studentID = t2.studentID
Order By Section,[Subject]
For Xml Path('X')), ' ', ',') As classes
From #testData t
Group By t.studentID
), classIDs As
(
Select Row_Number() Over (Order By classes) As classID,
Convert(XML,classes) As classes
From (Select Distinct classes
From studentClasses) sc
), breakOutClasses As
(
Select Row_Number() Over (Partition By cID,classID Order By classID) As nID,
n.cID,
n.classID,
t.split
From (Select Row_Number() Over (Partition By classID Order By classID) As cID,
classID,
Convert(Xml,'<X>'+Replace(t2.split,'_','</X><X>')+'</X>') As firstBreak
From classIDs c
Cross Apply (Select colData.D.value('.','Varchar(50)') As split
From c.classes.nodes('X') As colData(D)) t2) n
Cross Apply (Select colData.D.value('.','Varchar(50)') As split
From n.firstBreak.nodes('X') As colData(D)) As t
)
Select b1.classID, b1.split As [Subject], b2.split As Section Into #classes
From breakOutClasses b1
Join breakOutClasses b2
On b1.classID = b2.classID
And b1.cID = b2.cID
And b1.nID = 1
And b2.nID = 2
Order By classID, Section, [Subject];
If Object_ID('tempdb..#studentClassID') Is Not Null Drop Table #studentClassID;
With students As
(
Select t.StudentID,
Replace(( Select Convert(Varchar(10),[Subject])+'_'+Section As 'data()'
From #testData t2
Where t.studentID = t2.studentID
Order By Section,[Subject]
For Xml Path('')), ' ', ',') As classes
From #testData t
Group By t.studentID
), classes As
(
Select t.classID,
Replace(( Select Convert(Varchar(10),[Subject])+'_'+Section As 'data()'
From #classes t2
Where t.classID = t2.classID
Order By Section,[Subject]
For Xml Path('')), ' ', ',') As classes
From #classes t
Group By t.classID
)
Select c.classID, s.studentID Into #studentClassID
From classes c
Join students s
On c.classes = s.classes;
Select *
From #classes;
Select *
From #studentClassID;