计算从日期开始的周范围内的结果百分比

Calculate percentage of results in week ranges starting from date

我有一个 table 数据显示以下列的出勤率。

PupilID、AttendanceDate、AttendanceSession、IsInAttendance(1 或 0)

我需要能够定义开始日期和结束日期(学期日期),以便运行查询将显示每个学生每周的出勤率。

我可以使用以下代码找到每个学生的总百分比:

SELECT
    PupilID,
    ((SUM(CASE WHEN IsInAttendance = 1 THEN 1 ELSE 0 END) * 100) / COUNT(IsInAttendance))  AS TotalAttPct
FROM #CombinedAttClSe
GROUP BY PupilID

我有一年中的几周,代码如下:

DECLARE @StartDate DATETIME = '2011-09-01 00:00:00.000';
DECLARE @EndDate DATETIME = '2011-12-31 00:00:00.000';

;WITH GetDates AS
(
    SELECT
        DATEADD(DAY, 0, @startdate) AS TheDate,
        DATEPART(WK, DATEADD(DAY, 1, @startdate)) WkNo,
        DATEPART(YEAR, DATEADD(DAY, 1, @startdate)) DateYear
    UNION ALL
    SELECT
        DATEADD(DAY, 1, TheDate),
        DATEPART(WK, DATEADD(DAY, 1, TheDate)),
        DATEPART(YEAR, DATEADD(DAY, 1, TheDate))
        FROM GetDates
        WHERE TheDate < @enddate
)

SELECT
    WkNo,
    MIN(TheDate) AS SoW,
    MAX(TheDate) AS EoW
FROM GETDATES
GROUP BY WKNO
OPTION (MAXRECURSION 0);

我不知道从哪里开始输出这个数据如下:

学生ID |第 1 周 |第 2 周 |第三周 |第四周|等等

每个 'Week' 标题都包含一个数字以显示出席率。

编辑:

根据用户的建议,我尝试使用 PIVOT tables 和动态 SQL 来解决这个问题,但 运行 遇到了一些问题。以下是我目前的代码。

CREATE TABLE #yt 
(
  [PupilID] int, 
  [WeekNo] int, 
  [IsInAttendance] int
);

INSERT INTO #yt
(
  [PupilID], 
  [WeekNo],
  [IsInAttendance]
)
VALUES
    (102, 1, 1),
    (102, 1, 1),
    (102, 1, 1),
    (102, 1, 1),
    (102, 1, 0),
    (102, 1, 1),
    (102, 1, 0),
    (102, 1, 1),
    (102, 2, 1),
    (102, 2, 1),
    (102, 2, 1),
    (102, 2, 1),
    (102, 2, 1),
    (102, 2, 1),
    (102, 2, 0),
    (102, 2, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 1, 1),
    (101, 2, 1),
    (101, 2, 1),
    (101, 2, 1),
    (101, 2, 1),
    (101, 2, 0)

DECLARE @WkCols AS NVARCHAR(MAX),
        @WkQuery AS NVARCHAR(MAX)

select @WkCols = STUFF((SELECT ',' + QUOTENAME(WeekNo) 
                    FROM #yt
                    GROUP BY WeekNo
                    ORDER BY WeekNo
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @WkQuery = 'SELECT PupilID,' + @WkCols + ' FROM 
            (
                SELECT PupilID, WeekNo, IsInAttendance
                FROM #yt
            ) x
            PIVOT 
            (
                SUM(CASE WHEN IsInAttendance = 1 THEN 1 ELSE 0 END) * 100 / COUNT(IsInAttendance) 
                FOR WeekNo IN (' + @WkCols + ')
            ) p '

execute(@WkQuery);

目前我收到错误消息“关键字 'CASE' 附近的语法不正确”

如有任何指点或帮助,我们将不胜感激。

不幸的是,您不能在 PIVOT 聚合函数上应用复杂的聚合。因此,您将不得不使用简单的 SUMMAX。在旋转之前尝试计算出勤率:

SELECT
    T.PupilID,
    T.WeekNo,
    AttendancePercentage = SUM(T.IsInAttendance) * 100.0 / COUNT(1)
FROM
    #yt AS T
GROUP BY
    T.PupilID,
    T.WeekNo

和枢轴:

DECLARE @WkCols AS NVARCHAR(MAX),
        @WkQuery AS NVARCHAR(MAX)

select @WkCols = STUFF((SELECT ',' + QUOTENAME(WeekNo) 
                    FROM #yt
                    GROUP BY WeekNo
                    ORDER BY WeekNo
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @WkQuery = 'SELECT PupilID,' + @WkCols + ' FROM 
            (
                SELECT
                    T.PupilID,
                    T.WeekNo,
                    AttendancePercentage = SUM(T.IsInAttendance) * 100.0 / COUNT(1)
                FROM
                    #yt AS T
                GROUP BY
                    T.PupilID,
                    T.WeekNo
            ) x
            PIVOT 
            (
                MAX(AttendancePercentage) 
                FOR WeekNo IN (' + @WkCols + ')
            ) p '

execute(@WkQuery);