无法使用数据透视表显示正确的数据

时间:2013-12-02 18:12:08

标签: sql-server

表格结构:

enter image description here

这是我想使用数据透视表的数据

enter image description here

我想将结果显示为

教师活动[2013-11-22]等日期字段将显示出勤人数。

以下是我正在使用的代码,结果在每个日期下都为0,这是不正确的:

     DECLARE @temp AS TABLE(dates datetime)

        ;with cte (datelist, maxdate) as
        (
            select DATEADD(dd,-3,GETDATE()), GETDATE()
            union all
            select dateadd(dd, 1, datelist), maxdate
            from cte
            where datelist < maxdate
        )
        INSERT INTO @temp
        SELECT c.datelist
        FROM cte c 


        DECLARE @listdate nvarchar(MAX)  


        SELECT @listdate = (select(STUFF( (SELECT ', ' + QUOTENAME(convert(CHAR(10), dates, 120))                        
            from @temp ORDER BY dates asc                       
            FOR XML PATH('')),1, 1, '')))    

        print @listdate


        exec('(SELECT * INTO ##temptable from
        (select distinct teachername as Teacher,activityname AS Activity,memberid as attendance,
                QUOTENAME(convert(CHAR(10), attendancedate, 120)) AS DATES from
          tbteachertimelog inner join tbteacher on
        teacherid = tbteacher.id
        inner join tbactivity on tbactivity.id = tbteachertimelog.activityid
        left join tbattendance on tbattendance.activityid = tbteachertimelog.activityid and 
        convert(CHAR(10), tbattendance.attendancedate, 120) = convert(CHAR(10), tbteachertimelog.date, 120)
        group by teachername,activityname,memberid,
        attendancedate
        ) p            
        PIVOT            
        (            
        count(attendance)            
        FOR DATES IN ('+@listdate+')) AS pvt            
        )            

        ')
alter table ##temptable add TotalStudents int,meetings int,total64 int



    update ##temptable set TotalStudents = 
    (SELECT SUM(memcount) FROM (select count(distinct memberid) as memcount from tbteachertimelog 
    inner join tbattendance on tbattendance.activityid = tbteachertimelog.activityid and 
    convert(CHAR(10), tbattendance.attendancedate, 120) = convert(CHAR(10), tbteachertimelog.date, 120)
    where --teacherid = ##temptable.teacherid and tbteachertimelog.activityid = ##temptable.activityid
    --and
     tbattendance.attendancedate >= dateadd(dd,-7,getdate()) and  tbattendance.attendancedate <= getdate()
    group by convert(CHAR(10), tbattendance.attendancedate, 120)) x)

    update ##temptable set meetings = 
    (select count(distinct convert(CHAR(10), tbattendance.attendancedate, 120)) as dayscount from tbteachertimelog 
    inner join tbattendance on tbattendance.activityid = tbteachertimelog.activityid and 
    convert(CHAR(10), tbattendance.attendancedate, 120) = convert(CHAR(10), tbteachertimelog.date, 120)
    where teacherid = ##temptable.teacherid and tbteachertimelog.activityid = ##temptable.activityid)


    select * from ##temptable  

    drop table ##temptable

1 个答案:

答案 0 :(得分:5)

问题在于子查询中的以下行:

QUOTENAME(convert(CHAR(10), attendancedate, 120)) AS DATES

当您创建日期列表作为列标题时,QUOTENAME是必需的,但由于您将此列表添加到子查询中,因此表中的日期显示为:

DATES
[2013-11-22]
[2013-11-23]
[2013-11-24]

但是你想要在子查询中返回的日期应该没有括号:

DATES
2013-11-22
2013-11-23
2013-11-24

PIVOT功能正在查找与您的数据匹配的日期,但由于您的日期被方括号括起来,因此您不会得到任何匹配项,因此您将为所有内容返回零。

由于括号,您的列与您的数据不匹配 - 例如:

Header     --                YourDate
2013-11-22 -- does not match [2013-11-22]
2013-11-23 -- does not match [2013-11-23]
2013-11-24 -- does not match [2013-11-24]

查询应为:

exec('
with data as 
(
  SELECT * 
  from
  (
    select distinct teachername as Teacher,
      activityname AS Activity,
      memberid as attendance,
      convert(CHAR(10), attendancedate, 120) AS DATES 
    from tbteachertimelog 
    inner join tbteacher 
      on teacherid = tbteacher.id
    inner join tbactivity 
      on tbactivity.id = tbteachertimelog.activityid
    inner join tbattendance 
     on tbattendance.activityid = tbactivity.id
  ) p            
  PIVOT            
  (            
    count(attendance)            
    FOR DATES IN ('+@listdate+')
  ) AS pvt            
)            
select * 
from data 
')