[英]Stored procedure that returns a table with a matrix
我有以下3張桌子。
員工:
Name, LastName, SSN
課程實例:
Course, Year, Period
由出席:
Course, SSN, Year, Period, Hours
我正在嘗試制作一個存儲過程,該存儲過程返回給定年份中前4個課程實例的矩陣表(作為過程的參數)。
返回的矩陣需要看起來像這樣:
Name | LastName | Course | Course | Course | Course
這四個不同的Course
是給定年份的前四門課程,所以我現在得到的是這段代碼來查找那些課程:
DECLARE myCursor CURSOR FOR
SELECT top 4 Course
FROM Course Instance
WHERE Year = @year
ORDER by Period
矩陣的其余部分應僅以某種方式從上述表格中獲取值,基本上每個參加過任何課程的工作人員都應在矩陣中包含正確的信息。 在每個“ Course
列下,我希望得到與會人員的工作時間。
樣表
員工:
Name | LastName | SSN
Steve Lastname 234
Pete Steven 132
課程實例:
Course | Year | Period
DVA123 2013 1
DVA222 2014 2
由出席:
Course | SSN | Year | Period | Hours
DVA123 234 2013 1 200
DVA222 132 2014 2 50
預期的輸出:
Name | LastName | DVA123 | DVA222 | nothing | nothing
Pete Steven 200
Steve Lastname 50
我不確定CourseInstance的確切鏈接方式,但是您可以使用PIVOT和ROW_NUMBER來實現:
WITH Data AS
( SELECT s.Name,
s.LastName,
s.SSN,
ci.Course,
CourseNum = ROW_NUMBER() OVER(PARTITION BY s.SSN ORDER BY ci.Period)
FROM CourseInstance ci
INNER JOIN AttendedBy a
ON a.Course = ci.Course
AND a.Year = ci.Year
AND a.Period = ci.Period
INNER JOIN Staff s
ON s.SSN = a.SSN
WHERE ci.Year = @year
)
SELECT pvt.Name,
pvt.LastName,
Course1 = pvt.[1],
Course2 = pvt.[2],
Course3 = pvt.[3],
Course4 = pvt.[4]
FROM DATA
PIVOT
( MAX(Course)
FOR CourseNum IN ([1], [2], [3], [4])
) pvt;
它使用MAX(Course)
,但這並不是真正相關的,因為CourseNum
對於每個SSN
都是唯一的,您無論如何都只能選擇一行的最大值。 您可以輕松使用MIN
。
我一點也不提倡這種方法,但是,如果您選擇動態SQL方法而不是在表示層中這樣做,它將使您入門:
DECLARE @Courses NVARCHAR(MAX) = STUFF((SELECT TOP 4 ',' + QUOTENAME(course)
FROM ( SELECT course, Period, SortOrder = 0
FROM CourseInstance
WHERE Year = @Year
UNION ALL
-- THIS IS REQUIRED TO FILL GAPS WHERE THERE AREN'T ENOUGH COURSES
SELECT TOP 4
'Nothing' + CAST(ROW_NUMBER() OVER(ORDER BY object_id) AS CHAR(1)),
0,
1
FROM sys.all_objects
) t
ORDER BY SortOrder, Period, course
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
DECLARE @SQL NVARCHAR(MAX) =
' SELECT Name, LastName, ' + @Courses + '
FROM ( SELECT s.Name, s.LastName, s.SSN, ci.Course, a.Hours
FROM AttendedBy a
INNER JOIN Staff s
ON s.SSN = a.SSN
INNER JOIN CourseInstance ci
ON a.Course = ci.Course
AND a.Year = ci.Year
AND a.Period = ci.Period
) d
PIVOT
( SUM(Hours)
FOR Course IN (' + @Courses + ')
) pvt;';
EXECUTE SP_EXECUTESQL @SQL;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.