SQL 合并具有动态列标题的行

SQL merging rows with dynamic column headings

我正在尝试填充 Gridview 以便为每个学生启用 checkboxes,但取决于此查询中的某些值:

@SelectedDate 仅作为日期通过文本框提供

SELECT  v1.StudentID,
        v1.StudentPreferredName + ' ' + v1.StudentFamilyName AS StudentName,
        bcs.CheckStatusName,
        rce.DateSubmitted,
        rcp.RollCallPeriod
FROM tblBoardingRollCallEntries AS rce
     INNER JOIN vwBoardingTenants AS v1
        ON v1.StudentID = rce.StudentID
       AND v1.[Year] = YEAR(@SelectedDate)
     INNER JOIN tblBoardingCheckStatus AS bcs
        ON bcs.CheckStatusID = rce.CheckStatusID
       AND bcs.StatusActive = 1
     INNER JOIN tblBoardingRollCallPeriods AS rcp
         ON rcp.RollCallPeriodID = rce.RollCallPeriodID
        AND rcp.PeriodYear = YEAR(@SelectedDate)
        AND @SelectedDate BETWEEN rcp.PeriodStart AND rcp.PeriodEnd
        AND rcp.RowStatus = 1
WHERE dbo.fnDateOnly(rce.DateSubmitted) = dbo.fnDateOnly(@SelectedDate)

我的网格视图:

显示以下内容:

数据:

我希望能够基本上将 GridView 中的行压缩为每行一个学生,并根据 RollCallPeriod 文本勾选复选框。

我正在玩 SQL 枢轴,让数据尽可能接近我所追求的数据,以避免 code-behind,等等。但是,我无法做到这一点工作。

select StudentID, [1],[10],[2],[3],[4],[5],[6],[7],[8],[9]
      from
      (
        select StudentID, RollCallID, CheckStatusID
        from tblBoardingRollCallEntries
        unpivot
        (
          value for name in ([RollCallID],[StudentID],[CheckStatusID],[DateSubmitted],[StaffID])
        ) unpiv
      ) src
      pivot
      (
        sum(RollCallPeriodID)
        for RollCallPeriodID in ([1],[10],[2],[3],[4],[5],[6],[7],[8],[9])
      ) piv

我收到以下错误:

Lookup Error - SQL Server Database Error: The type of column "StudentID" conflicts with the type of other columns specified in the UNPIVOT list.

还有其他想法吗?

谢谢

两个选项:


  1. 而不是直接在 tblBoardingRollCallEntries 上逆透视:首先 select 列转换为派生 table 中的 VARCHAR(...) 类型,然后 UNPIVOT 派生 table。缩短示例:
select StudentID, RollCallID, CheckStatusID
from 
(
    SELECT ..., CAST(StudentId AS VARCHAR(128)) AS StudentId, ... FROM tblBoardingRollCallEntries)
) AS ups
unpivot
(
    value for name in ([RollCallID],[StudentID],[CheckStatusID],[DateSubmitted],[StaffID])
) unpiv

  1. 使用 CROSS APPLY (SELECT CAST(StudentId AS VARCHAR(128)) UNION ALL ... ) 逆透视,这样您就可以 UNPIVOT 将列直接转换为适当的类型。

根据您的实际数据,您可以通过多种方式执行此操作。

这将为您提供 CheckStatusName 作为 RollCallPeriod

的值
SELECT  *
FROM    (
            SELECT  StudentName,
                    CheckStatusName,
                    RollCallPeriod
            FROM    [YourQueryGoesHere]
        ) t 
PIVOT   ( 
    MAX(CheckStatusName) 
    FOR RollCallPeriod IN ([6:15 AM],[8:00 AM],[3:00 PM],[6:00 PM],[9:00 PM]) 
) p

或者您获得状态和 COUNT() 以显示该学生是否具有该 CheckStatusName, RollCallPeriod

的值
SELECT  *
FROM    (
            SELECT  StudentName,
                    CheckStatusName,
                    RollCallPeriod
            FROM    [YourQueryGoesHere]
        ) t 
PIVOT   ( 
    COUNT(RollCallPeriod) 
    FOR RollCallPeriod IN ([6:15 AM],[8:00 AM],[3:00 PM],[6:00 PM],[9:00 PM]) 
) p