动态Pivot Sql Server

时间:2016-08-22 16:57:32

标签: sql sql-server

我的查询非常简单,但我无法使其正常工作。 请帮忙。谢谢

我跟着啧啧但我的查询不起作用

DECLARE @ColumnName NVARCHAR(MAX) = ''
DECLARE @Query NVARCHAR(MAX) = ''
DECLARE @Site NVARCHAR(MAX) = ''
DECLARE @Date NVARCHAR(MAX) = ''
DECLARE @MOnth NVARCHAR(MAX) = ''


SELECT @ColumnName += QUOTENAME([Product Category]) + ','
FROM 
(
    SELECT DISTINCT [Product Category]
    FROM vw_TTMTALK_BREAKDOWN_DETAIL_LINE 
    WHERE [Customer No] = 'SLPIP' AND
    DATEPART(yyyy, [Posting Date])= '2016' AND
    CONVERT(CHAR(3), [Posting Date], 0)= 'Jan'
    GROUP BY [Customer No], [Product Category]
) AS T1

SET @ColumnName = LEFT(@ColumnName,LEN(@ColumnName)-1)

set @Site = 'SLPIP'
set @Date = '2016'
set @Month = 'Jan'

SET @Query = 'SELECT * FROM
(
SELECT [Customer No], [Product Category]
FROM vw_TTMTALK_BREAKDOWN_DETAIL_LINE 
WHERE [Customer No] = ' +  @Site + '  AND
DATEPART(yyyy, [Posting Date])=' + @Date + ' AND
CONVERT(CHAR(3), [Posting Date], 0)=' + @Month + '
--GROUP BY [Customer No], [Product Category]
) T2 
PIVOT (
  COUNT([Customer No])
  FOR [Product Category] IN (' + @ColumnName + ')
) T3'
--print @Query
EXEC sp_executesql @Query

错误

Msg 207, Level 16, State 1, Line 5
Invalid column name 'SLPIP'.
Msg 207, Level 16, State 1, Line 7
Invalid column name 'Jan'.

2 个答案:

答案 0 :(得分:2)

在构建查询时,需要使用带有SLPIP和Jan的引号,因为这些值是字符串

答案 1 :(得分:2)

首先,尝试尽可能多地使用参数化查询,并且只有在绝对必要时才使用字符串连接。

因此,通过修复它,您的查询应该看起来像这样:

DECLARE @ColumnName NVARCHAR(MAX) = '';
DECLARE @Query NVARCHAR(MAX) = '';
DECLARE @Site NVARCHAR(MAX) = '';
DECLARE @Date NVARCHAR(MAX) = '';
DECLARE @MOnth NVARCHAR(MAX) = '';

SELECT @ColumnName += ',' + QUOTENAME([Product Category])
FROM (
    SELECT DISTINCT [Product Category]
    FROM vw_TTMTALK_BREAKDOWN_DETAIL_LINE
    WHERE [Customer No] = 'SLPIP'
        AND DATEPART(yyyy, [Posting Date]) = '2016'
        AND CONVERT(CHAR(3), [Posting Date], 0) = 'Jan'
    GROUP BY [Customer No], [Product Category]
    ) AS T1;

SET @Site = 'SLPIP';
SET @Date = '2016';
SET @Month = 'Jan';

SET @Query = '
    SELECT *
    FROM (
        SELECT [Customer No], [Product Category]
        FROM vw_TTMTALK_BREAKDOWN_DETAIL_LINE 
        WHERE [Customer No] = @Site
            AND DATEPART(yyyy, [Posting Date]) = @Date
            AND CONVERT(CHAR(3), [Posting Date], 0) = @Month
        ) T2
    PIVOT (
        COUNT([Customer No])
        FOR [Product Category] IN (' + STUFF(@ColumnName, 1, 1, '') + ')
        ) T3';

EXEC sp_executesql @Query
    , N'@Site NVARCHAR(MAX), @Date NVARCHAR(MAX), @Month NVARCHAR(MAX)'
    , @Site
    , @Date
    , @Month;

我还鼓励您修改查询[发布日期]的方式

而不是:

AND DATEPART(yyyy, [Posting Date]) = '2016'
AND CONVERT(CHAR(3), [Posting Date], 0) = 'Jan'

我会这样重写:

AND [Posting Date] >= '2016-01-01'
AND [Posting Date] <  '2016-02-01';

这将使用[Posting Date]上的索引,如果有的话。