【问题标题】:Filling up dummy columns in pivot result sql server填充数据透视结果 sql server 中的虚拟列
【发布时间】:2014-05-17 19:52:08
【问题描述】:

我有一个包含以下列的考勤表:

StudentID, Date, Attendance

现在我正在运行查询以获取出勤结果

DECLARE @paramList VARCHAR(MAX)


SET @paramList = STUFF((SELECT DISTINCT ',[' + 
CONVERT(varchar(10), [Date], 20) + ']' 
FROM AttendenceT  
WHERE Date > '2014-01-01' AND Date < '2014-01-31' 
FOR XML PATH('') ) ,1,1,'')

DECLARE @query NVARCHAR(MAX)

SET @query = 'SELECT StudentID, ' + @paramList
+ ' FROM( SELECT * FROM AttendenceT)src 
PIVOT(SUM(Attendence) FOR Date IN (' + @paramList + ')) pvt'

EXEC sp_executesql @query

结果

结果没问题,除了考勤表中缺少天数,结果中没有可用的列。我想修改查询,以便即使出勤表中不存在日期,其列仍然可用。

请注意,我不是 SQL 专家。我使用 google 创建了这个查询,并且大部分是过去问题的 stackoverflow 答案。

【问题讨论】:

    标签: sql sql-server pivot


    【解决方案1】:

    首先得到一个日历表。这是一个涉及该主题的SO post。该表是永久部分还是您的数据库或临时表或表变量都没有关系。让我们将此表称为Calendar,其中一列称为TheDate

    接下来将Calendar 加入到所有学生的列表中。我将使用您的 AttendenceT 表,因为这是您在问题中提到的唯一一个。如果你有一个实际的Student 表会更好,因为最终结果甚至会列出那些从未参加过的学生(我认为这将是有用的信息)。

    select
        s.StudentID
        ,c.TheDate
    from Calendar as c
    cross apply (
            select distinct StudentID from AttendenceT -- Put the Student table here if you have one
            ) as s;
    

    您很可能只需要某个数据范围,因此如果需要,请添加 WHERE 子句。

    然后您可以将其加入到您的出勤表中:

    select
        s.StudentID
        ,c.TheDate
        ,ISNULL(a.Attendance, 0)
    from Calendar as c
    cross apply (
            select distinct StudentID from AttendenceT
            ) as s
    left outer join AttendenceT as a
        on a.StudentID = s.StudentID
        and a.Date = c.TheDate
    -- optional for a limited date range.
    where c.TheDate between <your star date> and <your end date>;
    

    这将在您的范围内的每个日期为您提供每个学生,以及存在的出勤率。 ISNULL() 负责处理不存在的示例。

    将此查询的输出存储到临时表中:

    select
        ...
    into #TempAttendence
    from ... etc.
    

    在您发布的查询中,将所有对AttendenceT 的引用替换为#TempAttendence,您将获得所需的输出。

    【讨论】:

    • 感谢迈克尔·格林。这已经解决了除了 NULL 问题之外的问题。当我使用 ISNULL(a.Attendance, 0) 时,我收到以下错误消息对象或列名丢失或为空。对于 SELECT INTO 语句,验证每一列都有一个名称。对于其他语句,请查找空别名。不允许使用定义为 "" 或 [] 的别名。将别名更改为有效名称。
    • 通过将值更新为 ISNULL(a.Attendence, 0) AS Attendence 修复了错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    相关资源
    最近更新 更多