Sql server 转换数据透视查询中的数据类型时出错

Sql server 转换数据透视查询中的数据类型时出错,sql-server,Sql Server,我想将下面的数据转换为SQL中的pivot。(显示对应列“weeks”和对应行“names”的“total”值),并在运行sp时引发异常: 将数据类型nvarchar转换为datetime时出错 及 PIVOT运算符中提供了不正确的值“@Week1” 我的问题是: [Name] [nvarchar](255) NULL, [Weeks] [DATETIME] NULL, [total] [float] NULL @Week1 = '12/6/2015' @Week2 = '12/13/201

我想将下面的数据转换为SQL中的pivot。(显示对应列“weeks”和对应行“names”的“total”值),并在运行sp时引发异常:

将数据类型nvarchar转换为datetime时出错

PIVOT运算符中提供了不正确的值“@Week1”

我的问题是:

[Name] [nvarchar](255) NULL,
[Weeks] [DATETIME] NULL,
[total] [float] NULL

@Week1 = '12/6/2015'
@Week2 = '12/13/2015'
@Week3 = '12/20/2015'
@Week4 = '12/27/2015'

SELECT Name, @Week1 AS Week1, @Week2 AS Week2, @Week3 AS Week3, @Week4 AS Week4
INTO #TempData 
FROM 
(
    SELECT Name, Weeks, total FROM #TempData2
) Data 
PIVOT
(
       SUM([total])
       FOR [Weeks] IN ([@Week1],[@Week2],[@Week3],[@Week4])
) Piv
我为所有列提供了数据类型为
datetime
,但它将
nvarchar
抛出到
datetime
错误。我尝试过一些解决方案,但不起作用


感谢您的帮助…

在透视查询中使用变量作为列占位符是行不通的。使用以下SQL查询后,我可以生成大部分结果:

SELECT
  Name,
  [2015-12-06 00:00:00] AS '12/6/2015',
  [2015-12-13 00:00:00] AS '12/13/2015',
  [2015-12-20 00:00:00] AS '12/20/2015',
  [2015-12-27 00:00:00] AS '12/27/2015'
FROM 
(
    SELECT Name, Weeks, total 
    FROM #TempData
) Data 
PIVOT
(
       SUM([total])
       FOR [Weeks] IN ([2015-12-06 00:00:00], [2015-12-13 00:00:00], [2015-12-20 00:00:00],[2015-12-27 00:00:00])
) Piv
生成如下所示的输出,但正如您将看到的,Total列不存在

为了添加
grandtotal
列,您需要创建一个派生表,对总计进行求和,然后将其联接。比如:

SELECT T1.*, T2.GrandTotal
FROM
(
    SELECT
      Name,
      [2015-12-06 00:00:00] AS '12/6/2015',
      [2015-12-13 00:00:00] AS '12/13/2015',
      [2015-12-20 00:00:00] AS '12/20/2015',
      [2015-12-27 00:00:00] AS '12/27/2015'
    FROM 
    (
        SELECT Name, Weeks, total FROM #TempData
    ) Data 
    PIVOT
    (
      SUM([total])
      FOR [Weeks] IN
      (
        [2015-12-06 00:00:00], [2015-12-13 00:00:00],
        [2015-12-20 00:00:00], [2015-12-27 00:00:00]
      )
    ) Piv
) T1
JOIN
(
  SELECT Name, SUM(Total) AS GrandTotal
  FROM #TempData
  WHERE Weeks IN 
  (
    '2015-12-06 00:00:00',
    '2015-12-13 00:00:00',
    '2015-12-20 00:00:00',
    '2015-12-27 00:00:00'
  )
  GROUP BY Name
) AS T2 ON T2.Name = T1.Name
结果:

您可以对SQL进行泛化,这样就不必多次键入日期。在下面的SQL命令中,我假设您想要相邻的几周,如示例数据中所示:

DECLARE @StartDate datetime = '2015-12-06 00:00:00';
DECLARE @StartWeek int;
SELECT @StartWeek = DATEPART(WEEK, @StartDate);

SELECT Name, [0], [1], [2], [3]
FROM 
(
  SELECT
    Name,
    DATEPART(WEEK, Weeks) - @StartWeek AS WeekNumber,
    Total 
  FROM #TempData
  WHERE DATEPART(WEEK, Weeks) BETWEEN @StartWeek AND (@StartWeek + 3)
) Data 
PIVOT
(
    SUM([total])
    FOR [WeekNumber] IN ([0], [1], [2], [3])
) Piv
这将产生以下结果。虽然列标题已作为日期丢失,但您可以通过更改单个变量来更改日期


为了消除转换错误,您需要将@Week1、@Week2等变量声明为
datetime
,并使用以下格式设置它们的值:
2015-12-6 00:00:00
。我已经尝试过了。但它显示了同样的错误。所有参数和变量都是datetime格式。如果您能接受答案,我将不胜感激。