0

我被要求将一些数据显示为数据透视表以使其更具可读性,因此经过一些研究后将这个查询放在一起:

SELECT
    regionName,
    [Not Yet Set],
    [Not Applicable],
    [Not met],
    [Achieved],
    [Excelled],
    [Accepted],
    [Declined]
FROM
    (
    SELECT
        regionID,
        regionName,
        resultID,
        resultDesc
    FROM
        @tbl_results) ps
PIVOT
    (
        COUNT (resultID)
        FOR resultDesc IN
            (
            [Not Yet Set],
            [Not Applicable],
            [Not met],
            [Achieved],
            [Excelled],
            [Accepted],
            [Declined]
            )) as pvt

...产生:

regionName      Not Yet Set Not Applicable Not met  Achieved  Excelled Accepted  Declined
--------------------------------------------------------------------------------------
China           3           2              1        0         0        0         0
United Kingdom  8           0              1        2         0        0         1

但是据我了解,pvt 中引用的列必须与基础表中的数据库行值完全匹配。这是一个问题,所以我重写了查询以使用 ID 值

SELECT
    regionName,
    [1] as [Not yet set],
    [2] as [Not applicable],
    [3] as [Not met],
    [4] as [Achieved],
    [5] as [Excelled],
    [6] as [Accepted],
    [7] as [Declined]
FROM
    (
    SELECT
        regionID,
        regionName,
        resultID,
        resultDesc
    FROM
        @tbl_results) ps
PIVOT
    (
        COUNT (resultID)
        FOR resultID IN ([1],[2],[3],[4],[5],[6],[7])) as pvt

这会产生这个结果集:

regionName      Not yet set  Not applicable    Not met    Achieved    Excelled    Accepted    Declined
------------------------------------------------------------------------------------------------------
United Kingdom  0            0                 0          2           0           0           0
United Kingdom  0            0                 0          0           0           0           1
United Kingdom  0            0                 1          0           0           0           0
United Kingdom  8            0                 0          0           0           0           0
China           0            2                 0          0           0           0           0
China           0            0                 1          0           0           0           0
China           3            0                 0          0           0           0           0

任何人都可以向我解释为什么在使用 resultID 来执行 COUNT 的情况下,为什么 regionNames 在上述查询中会重复?

此外,数据透视表中使用的 resultDesc 列是硬编码的(结果表中只有这七个潜在值)。是否可以动态提取这些内容,以便在创建新数据库行时不必更新过程?甚至更好的是,仅包含在 @tbl_results 中的描述,例如枢轴使用SELECT DISTINCT resultID, resultDesc FROM @tbl_results

4

1 回答 1

3

您的第二个查询的问题是resultDescGROUP BYfor 中使用了PIVOT并且您有不同的值,因此您为每个resultDesc.

第二个查询应该是:

SELECT
    regionName,
    [1] as [Not yet set],
    [2] as [Not applicable],
    [3] as [Not met],
    [4] as [Achieved],
    [5] as [Excelled],
    [6] as [Accepted],
    [7] as [Declined]
FROM
    (
    SELECT
        regionID,
        regionName,
        resultID
    FROM
        @tbl_results) ps
PIVOT
    (
        COUNT (resultID)
        FOR resultID IN ([1],[2],[3],[4],[5],[6],[7])) as pvt

请参阅SQL Fiddle with Demo

如果要使用resultDesc,则可以删除 ,resultId因此查询为:

SELECT
    regionName,
    [Not yet set],
    [Not applicable],
    [Not met],
    [Achieved],
    [Excelled],
    [Accepted],
    [Declined]
FROM
    (
    SELECT
        regionID,
        regionName,
        resultDesc
    FROM
        tbl_results) ps
PIVOT
    (
        COUNT (resultDesc)
        FOR resultDesc IN ([Not yet set],[Not applicable],
                           [Not met],[Achieved],[Excelled],
                           [Accepted],[Declined])) as pvt

请参阅SQL Fiddle with Demo

如果要动态执行此操作,则可以使用:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(resultDesc) 
                    from tbl_results
                    group by resultid, resultDesc
                    order by resultid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT regionname, ' + @cols + ' from 
             (
                select regionid, regionname, resultdesc
                from tbl_results
            ) x
            pivot 
            (
                count(resultdesc)
                for resultdesc in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo

编辑#1,根据您的评论,您得到的错误是因为临时表超出了动态 SQL 的范围。因此,您将需要创建一个用户定义类型的表,类似于:

create type mytable as table
(
  regionid int,
  regionname varchar(50),
  resultid int,
  resultdesc varchar(50)
);

然后将表传递到动态 sql 中:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(resultDesc) 
                    from @tbl_results
                    group by resultid, resultDesc
                    order by resultid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT regionname, ' + @cols + ' from 
             (
                select regionid, regionname, resultdesc
                from @tbl_results
            ) x
            pivot 
            (
                count(resultdesc)
                for resultdesc in (' + @cols + ')
            ) p '

EXECUTE sp_executesql @query, N'@tbl_results mytable READONLY', @tbl_results

请参阅带有演示的 SQL Fiddle

于 2013-02-21T13:51:53.263 回答