旋转 sql 服务器 table

Pivoting an sql server table

如何使用 SQL 查询将 SQL 服务器 table meterdata 转换为 Result_Table

MeterData table 存储功率和频率并具有主键 (meterno, date, timeblock) 并且 meterno 列具有变量号。的价值。

MeterData table:

meterno date      timeblock power   frequency       
--------------------------------------------------
89      1-Apr-16    1       500       50.02     
89      1-Apr-16    2       100       49.99     
90      1-Apr-16    1       200       50.02     
90      1-Apr-16    2       300       49.89     

Result_Table

date    timeblock   89_power 90_power   89_frequency 90_frequency   
1-Apr-16    1       500      200        50.02       50.02   
1-Apr-16    2       100      300        49.99       49.89

为简单起见,我们假设 meterno 列已固定编号。值说 (89,90)。我正在尝试以下查询但没有得到结果。有人可以编辑查询,以便输出 Results_Table as above.Also 最好请使用数据透视查询回答。查询是

SELECT
*
 FROM
 (
    SELECT
 *
    FROM meterdata  
 ) AS P
PIVOT
(
  sum (power ) FOR meterno IN (89, 90)
) AS pv1 
PIVOT
(
  sum (frequency ) FOR meterno IN (89, 90)
) AS pv2 

GO

这是一个您可以尝试的数据透视查询,它不使用 SQL 服务器 PIVOT 操作:

SELECT date, timeblock
    SUM(CASE WHEN meterno=89 THEN power     ELSE 0 END) AS meterno-89_power,
    SUM(CASE WHEN meterno=90 THEN power     ELSE 0 END) AS meterno-90_power,
    SUM(CASE WHEN meterno=89 THEN frequency ELSE 0 END) AS meterno-89_frequency,
    SUM(CASE WHEN meterno=90 THEN frequency ELSE 0 END) AS meterno-89_frequency
FROM MeterData
GROUP BY date, timeblock

Dynamic SQL 会帮助你(我使用了 ##MeterDatatempdb 你必须使用你实际的 table 和数据库名称)。将与源 table 中的任意数量的列一起使用。几条评论:

  • 您需要 CASTCONVERT 所有列为一种类型(我在 @p 变量中使用了 nvarchar(10));
  • 我排除了 meternodatetimeblock 列,因为它们在您的数据集中没有用作 参数
  • 您可以在执行前PRINT @sql查看已形成的要执行的内容。

这里是查询:

DECLARE @p nvarchar(max), @c nvarchar(max), @s nvarchar(max), @sql nvarchar(max)

--That will get you this:
--,CAST([power] as nvarchar(10)) [power],CAST([frequency] as nvarchar(10)) [frequency]
SELECT @p = (
SELECT ',CAST(' + QUOTENAME(COLUMN_NAME) + ' as nvarchar(10)) '+ QUOTENAME(COLUMN_NAME)
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock')
FOR XML PATH('')
)
--[power],[frequency]
SELECT @c = STUFF((
SELECT ',' + QUOTENAME(COLUMN_NAME) 
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock')
FOR XML PATH('')),1,1,'')
--[frequency89],[frequency90],[power89],[power90]
SELECT @s = STUFF((
SELECT DISTINCT ','+QUOTENAME(COLUMN_NAME + CAST(meterno as nvarchar(10)))
FROM ##MeterData m
CROSS JOIN (
    SELECT COLUMN_NAME
    FROM tempdb.INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock')
) as p 
FOR XML PATH('')),1,1,'')
--Put it all in dynamic query
SELECT @sql = '
SELECT *
FROM (
    SELECT  [date],
            timeblock,
            params + CAST(meterno as nvarchar(10)) as params,
            [values]
    FROM (
        SELECT  meterno, 
                [date], 
                timeblock'
                +@p+
                '
        FROM ##MeterData
        ) as p
    UNPIVOT (
        [values] FOR params IN ('+@c+')
    ) as unpvt
) as p2
PIVOT (
    MAX([Values]) FOR params IN ('+@s+')
) as pvt'
--And execute
EXEC sp_executesql @sql

输出:

date        timeblock   frequency89 frequency90 power89 power90
2016-04-01  1           50.02       50.02       500     200
2016-04-01  2           49.99       49.89       100     300