带一行四列的数据透视表

时间:2012-02-14 03:16:06

标签: sql-server sql-server-2008 tsql

 -- Pivot table with one row and four columns

SELECT 'Values' tValues, 
    ID,Name,ValueID,Value FROM (

        Select ID,Name,ValueID,Value FROM Table WHERE OptionID = 1000000

    ) AS SourceTable 

    PIVOT ( 

        COUNT(tValues)
        FOR tValues IN ( ID,Attribute,ValueID,Value ) 

    ) AS PivotTable;

我将离开Microsoft.com上的示例:http://msdn.microsoft.com/en-us/library/ms177410.aspx

但有一些关于Pivot的东西我真的不明白,所以当你在上面的代码中看到它时不要感到惊讶,比如COUNT(tValues),我不知道这是为了什么,从微软的例子来看,它似乎总是某种数值,所以我想我会试着看它是否会返回一些东西,但它返回的只是一个错误。无论如何,如果那里有人可以分享为什么这个查询不起作用,并可能解释FOR上方的数值是用于什么?

Table包含x行数,包含四列,所以它看起来像这样:

 ID  |  Name   |  ValueID  |  Value

 100 |  Color  |  10000    |  Black
 101 |  Size   |  10005    |  Large

输出应该是这样的:

 Name_100  |  Color   |  Name_101  |  Size  |

 10000     |  Black   |  10005     |  Large |

2 个答案:

答案 0 :(得分:1)

如果你想使用具有可变数量列的数据透视表,那么我建议使用类似的东西;

   DECLARE @cols VARCHAR(4000)
   DECLARE @query VARCHAR(8000)
   SELECT  @cols = STUFF(( SELECT DISTINCT
            '],[' + Name
                       FROM    Table
                       ORDER BY '],[' + Name
                       FOR XML PATH('')
                     ), 1, 2, '') + ']'

   SET @query =
   'SELECT * FROM
   (
        SELECT col1, col2, col3, whateverColYourInterestedIn, Name, Value
        FROM Table
   )t
   PIVOT (MAX(Value) FOR Name
   IN ('+@cols+')) AS pvt'

   EXECUTE (@query)

这可能不太对,但它应该成为你的起点。

有关详细信息,请查看thisthis等链接。

答案 1 :(得分:1)

这样的事可能。

仅当名称列为唯一时才有效。如果没有,那么你可能想在其上附加一个id。

首先是一些测试数据:

CREATE TABLE tblValues
    (
        ID INT,
        Name VARCHAR(100),
        ValueID INT, 
        Value VARCHAR(100)
    )

INSERT INTO tblValues
VALUES
    (100,'Color',10000,'Black'),
    (101,'Size',10005,'Large')

然后你需要让列可以转动:

DECLARE @cols VARCHAR(MAX)
;WITH CTE AS
(
    SELECT
        'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name,
        'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort,
        tbl.ID
    FROM
        tblValues AS tbl
    UNION ALL
    SELECT
        tbl.Name,
        'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort,
        tbl.ID
    FROM
        tblValues AS tbl
)
SELECT
    @cols = COALESCE(@cols + ','+QUOTENAME(Name),
                 QUOTENAME(Name))
FROM
    CTE
ORDER BY
    CTE.ID,
    CTE.Sort

然后声明并执行动态sql,如下所示:

DECLARE @query NVARCHAR(4000)=
N'SELECT
    *
FROM
(
    SELECT
        ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName,
        CAST(tbl.ValueID AS VARCHAR(100)) AS name
    FROM
        tblValues AS tbl
    UNION ALL
    SELECT
        tbl.Name AS pivotName,
        tbl.Value AS name
    FROM
        tblValues AS tbl
) AS p
PIVOT
(
    MAX(name)
    FOR pivotName IN ('+@cols+')
) AS pvt'

EXECUTE(@query)

然后在我的情况下,我将删除我创建的表

DROP TABLE tblValues

修改

或者你的情况应该是这样的:

首先是列:

DECLARE @cols VARCHAR(MAX)
;WITH CTE AS
(
    SELECT
        'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Name,
        'Name_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort,
        tbl.ID
    FROM
        [Table] AS tbl
    WHERE
        tbl.OptionID = 1000000
    UNION ALL
    SELECT
        tbl.Name,
        'Value_'+CAST(tbl.ID AS VARCHAR(100)) AS Sort,
        tbl.ID
    FROM
        [Table] AS tbl
    WHERE
        tbl.OptionID = 1000000
)
SELECT
    @cols = COALESCE(@cols + ','+QUOTENAME(Name),
                 QUOTENAME(Name))
FROM
    CTE
ORDER BY
    CTE.ID,
    CTE.Sort

然后是动态sql。

DECLARE @query NVARCHAR(4000)=
N'SELECT
    *
FROM
(
    SELECT
        ''Name_''+CAST(tbl.ID AS VARCHAR(100)) AS pivotName,
        CAST(tbl.ValueID AS VARCHAR(100)) AS name
    FROM
        [Table] AS tbl
    WHERE
        tbl.OptionID = 1000000
    UNION ALL
    SELECT
        tbl.Name AS pivotName,
        tbl.Value AS name
    FROM
        [Table] AS tbl
    WHERE
        tbl.OptionID = 1000000
) AS p
PIVOT
(
    MAX(name)
    FOR pivotName IN ('+@cols+')
) AS pvt'

EXECUTE(@query)

您无需创建表格或删除表格。那只是因为我的数据库中没有你的表,如果其他人想要运行这个例子。