与 SQL 数据透视查询语法作斗争

Struggling with SQL Pivot Query Syntax

谁能告诉我我的 SQL 出了什么问题,今天遇到这个问题。错误是:

Msg 156, Level 15, State 1, Line 11

Incorrect syntax near the keyword 'select'.

Msg 102, Level 15, State 1, Line 11

Incorrect syntax near ')'.

SELECT *
FROM (
    SELECT 
        left(datename(month,TransactionDateTime),3) as [month], year(TransactionDateTime) as [year],
        count(*) as Total 
    FROM quotations
) as s
PIVOT
(
    SUM(Total)
    FOR [year] IN (select distinct year(TransactionDateTime) from quotations)
) AS pivot

我所追求的形状是...如此年作为列名,然后每个月 12 行。下面只是为了说明形状

        //   var data = google.visualization.arrayToDataTable([
        //  ['Month', '2013', '2014', '2015'],
        //  ['Jan', 10, 30, 31],
        //  ['Feb', 11, 30, 32],
        //]);

数据透视的语法如下(From TechNet):

PIVOT
(
    <aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column], ... [last pivoted column])
) AS <alias for the pivot table>

您可以看到在 IN 子句中应该有包含在 [] 中的列名,如果列名是动态的,这可能是一个问题。使用动态 SQL 可以轻松解决此问题。

这是一个例子:

DECLARE @cols AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(year(TransactionDateTime))
            FROM Quotations
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @query = 
    'SELECT *
    FROM (
        SELECT 
            left(datename(month,TransactionDateTime),3) as [month], year(TransactionDateTime) as [year],
            count(*) as Total 
        FROM quotations
    ) as s
    PIVOT
    (
        SUM(Total)
        FOR [year] IN (' + @cols + ')
    ) AS pivot'

EXECUTE(@query)

我不知道您的架构是什么,因此 table/column 名称可能有误。如果这没有帮助,如果您共享您的架构和示例数据,我可以更精确。

问题出在您查询的以下部分

(select distinct year(TransactionDateTime) from quotations)

您需要在 in 子句中提供静态的年份列表。