数据透视表错误

时间:2013-05-10 23:53:21

标签: sql sql-server pivot

为什么,为什么,为什么?我收到错误:

“Msg 325,Level 15,State 1,Line 17 'PIVOT'附近的语法不正确。您可能需要将当前数据库的兼容级别设置为更高的值才能启用此功能。请参阅存储过程sp_dbcmptlevel的帮助。“ 对于这个查询?

WITH Offnet7 AS (
    SELECT  disposition.dispositiondesc, interaction.dispositionid, DATEPART(wk,interaction.ibegintime) as iWeek

    FROM    interaction INNER JOIN
            disposition ON interaction.reasonid = disposition.dispositionid

    WHERE   interaction.dispositionid = 10 and (reasonid = 20365 or reasonid = 20366 or reasonid = 11168) and
            interaction.ibegintime >= '2013-1-1' and
            interaction.ibegintime < '2014-1-1'
)

SELECT  iWeek, dispositiondesc, count(iWeek) as 'OffnetCounts'
FROM Offnet7 

Group by dispositiondesc, iWeek

PIVOT
(
    OffnetCounts
    for iWeek in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15])  
) AS counts

编辑: 试图制作一个SQL小提琴,当我去“构建架构”时它被扼杀了。 (SQL Noob) 我从SQL管理工作室的对象资源管理器中提取了类型并复制了一些示例数据。但这就是我的尝试:

CREATE TABLE interaction
    ([reasonid] int, [dispositionid] int, [ibegintime] datetime)
;

INSERT INTO interaction
    ([reasonid], [dispositionid], [ibegintime])
VALUES
    (20366, 10, '2012-01-31 23:59:48.000'),
    (20366, 10, '2012-02-07 14:03:01.000'),
    (20366, 10, '2012-02-07 14:06:48.000'),
    (20366, 10, '2012-02-13 21:44:10.000'),
    (20366, 10, '2012-02-27 21:36:33.000')
;


CREATE TABLE disposition
    ([dispositionid] int, [predefined] int, [dispositiondesc] varchar(64), [displayvalue] varchar(254))
;

INSERT INTO disposition
    ([dispositionid], [predefined], [dispositiondesc], [displayvalue])
VALUES
(10, 1, 'TRANSFERRED OFFNET', 'TRANSFERRED OFFNET'),
    (11168, 0, 'TAKEDA PASSWORD', 'TAKEDA PASSWORD'),
    (15433, 0, 'Voice Mail - TAKEDAEMEA', 'Voice Mail - TAKEDAEMEA'),
    (20365, 0, 'TAKEDA iPAD, iPhone or BlackBerry', 'TAKEDA iPAD, iPhone or BlackBerry'),
    (20366, 0, 'TAKEDA Concur', 'TAKEDA Concur')
;

结论: 感谢Bluefeet的所有帮助!

对于对此感兴趣的任何人,如果我的DBA正确设置了SQL兼容性级别,那么他的第一个答案将起作用。在尝试了他的第一个答案后,我得到了一个:

"Msg 102, Level 15, State 1, Line 19 Incorrect syntax near '('."

因为DBA没有为SQL Server配置支持PIVOT语句的兼容级别。

1 个答案:

答案 0 :(得分:2)

您的语法已关闭。 PIVOT正在进行GROUP BY和聚合。在我看来,你想要使用:

WITH Offnet7 AS 
(
  SELECT  disposition.dispositiondesc, 
    interaction.dispositionid, 
    DATEPART(wk,interaction.ibegintime) as iWeek
  FROM    interaction 
  INNER JOIN disposition 
    ON interaction.reasonid = disposition.dispositionid
  WHERE   interaction.dispositionid = 10 
    and (reasonid = 20365 or reasonid = 20366 or reasonid = 11168) 
    and interaction.ibegintime >= '2013-1-1' 
    and interaction.ibegintime < '2014-1-1'
)
SELECT  dispositiondesc, 
  [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15]
FROM Offnet7 
PIVOT
(
    count(dispositionid)
    for iWeek in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15])  
) AS counts;

请参阅Demo

这将创建一个数据表,其中包含每周dispositionid的计数,按dispositiondesc分组。

编辑,这也可以使用带有CASE表达式的聚合函数来完成:

SELECT  disposition.dispositiondesc, 
  sum(case when DATEPART(wk,interaction.ibegintime) = 1 then 1 else 0 end) [1],
  sum(case when DATEPART(wk,interaction.ibegintime) = 2 then 1 else 0 end) [2],
  sum(case when DATEPART(wk,interaction.ibegintime) = 3 then 1 else 0 end) [3],
  sum(case when DATEPART(wk,interaction.ibegintime) = 4 then 1 else 0 end) [4],
  sum(case when DATEPART(wk,interaction.ibegintime) = 5 then 1 else 0 end) [5],
  sum(case when DATEPART(wk,interaction.ibegintime) = 6 then 1 else 0 end) [6],
  sum(case when DATEPART(wk,interaction.ibegintime) = 7 then 1 else 0 end) [7],
  sum(case when DATEPART(wk,interaction.ibegintime) = 8 then 1 else 0 end) [8],
  sum(case when DATEPART(wk,interaction.ibegintime) = 9 then 1 else 0 end) [9],
  sum(case when DATEPART(wk,interaction.ibegintime) = 10 then 1 else 0 end) [10],
  sum(case when DATEPART(wk,interaction.ibegintime) = 11 then 1 else 0 end) [11],
  sum(case when DATEPART(wk,interaction.ibegintime) = 12 then 1 else 0 end) [12],
  sum(case when DATEPART(wk,interaction.ibegintime) = 13 then 1 else 0 end) [13],
  sum(case when DATEPART(wk,interaction.ibegintime) = 14 then 1 else 0 end) [14],
  sum(case when DATEPART(wk,interaction.ibegintime) = 15 then 1 else 0 end) [15]
FROM    interaction 
INNER JOIN disposition 
  ON interaction.reasonid = disposition.dispositionid
WHERE   interaction.dispositionid = 10 
  and (reasonid = 20365 or reasonid = 20366 or reasonid = 11168) 
  and interaction.ibegintime >= '2013-1-1' 
  and interaction.ibegintime < '2014-1-1'
group by disposition.dispositiondesc;

请参阅SQL Fiddle with Demo