带有子查询的MS SQL Server数据透视表

时间:2012-11-06 06:09:06

标签: sql sql-server tsql subquery pivot

我确定这是一项简单的技术,但到目前为止我找不到答案!

我有

TIMESTAMP           | POINTNAME | VALUE
2012-10-10 16:00:00   AHU01       20
2012-10-10 16:00:00   AHU02       25
2012-10-10 16:00:15   AHU01       26
2012-10-10 16:00:15   AHU02       35

等......(大约800个POINTNAMES)

有很多点名我不想在每个点'FOR'的'IN'子句中列出每一个 (如下面给出的语法)定义,但是想使用子查询。

所以我想要的是将所有POINTNAME值作为具有TIMESTAMP和VALUE列的列,因此我将获得一个TIMESTAMP值和每个POINTNAME的多个列,每个POINTNAME PER TIMESTAMP只有一个值所以我不这样做需要聚合任何东西,所以只需选择max吗?

类似的东西:

SELECT [TIMESTAMP] FROM ( SELECT * FROM POINT_TABLE)
PIVOT( Max[Value] FOR [POINTNAME] IN (SELECT DISTINCT [POINTNAME] FROM POINT_TABLE)

会产生 -

   TIMESTAMP              AHU01          AHU02
 2012-10-10 16:00:00        20             25
 2012-10-10 16:15:00        26             35

我意识到这可能不是那么简单,但希望你能得到我想要实现的目标吗?

PIVOT SYNTAX:

SELECT <non-pivoted column>,
    [first pivoted column] AS <column name>,
    [second pivoted column] AS <column name>,
    ...
    [last pivoted column] AS <column name>
FROM
    (<SELECT query that produces the data>) 
    AS <alias for the source query>
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>
<optional ORDER BY clause>;

1 个答案:

答案 0 :(得分:12)

对于动态数量的列,您必须使用动态SQL

declare
    @cols nvarchar(max),
    @stmt nvarchar(max)

select @cols = isnull(@cols + ', ', '') + '[' + T.POINTNAME + ']' from (select distinct POINTNAME from TABLE1) as T

select @stmt = '
    select *
    from TABLE1 as T
        pivot 
        (
            max(T.VALUE)
            for T.POINTNAME in (' + @cols + ')
        ) as P'

exec sp_executesql  @stmt = @stmt

SQL FIDDLE EXAMPLE