【发布时间】:2018-03-27 13:10:03
【问题描述】:
我有一个数据表,其中包含以下列显示出勤率。
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 周 |第 3 周 |第 4 周|等
每个“周”标题都包含一个数字以显示出勤率。
编辑:
根据用户的建议,我尝试使用 PIVOT 表和动态 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 表 - 它们有时有点复杂,但对于将行转换为列很有用。
-
您需要使用
BETWEEN将#CombinedAttClSe 与Weeks 间隔连接起来,然后使用动态SQL 旋转结果(因为您不知道您的参数将包括多少周)。跨度> -
@EzequielLopezPetrucci 您好 Ezeuiel,我不确定我是否理解您所说的“以周间隔加入 #CombinedAttClSe”是什么意思。对不起,如果我遗漏了一些简单的东西,但你能进一步解释吗?
-
我猜该表 #CombinedAttClSe 包含每个学生在特定日期的出勤率。如果是这样,您需要将该表与第二个查询中的最后一个查询(具有 WkNo 和 Min/Max 日期的那个)连接起来,这样您就可以知道学生每周的出勤率。
-
是的,这行得通。只需确保“xCount”列(在您提到的链接中)在旋转之前已经包含出勤率。
标签: sql sql-server pivot pivot-table dynamic-sql