簡體   English   中英

存儲過程返回帶有矩陣的表

[英]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的確切鏈接方式,但是您可以使用PIVOTROW_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM