旋转 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 会帮助你(我使用了 ##MeterData
和 tempdb
你必须使用你实际的 table 和数据库名称)。将与源 table 中的任意数量的列一起使用。几条评论:
- 您需要
CAST
或 CONVERT
所有列为一种类型(我在 @p
变量中使用了 nvarchar(10)
);
- 我排除了
meterno
、date
、timeblock
列,因为它们在您的数据集中没有用作 参数 ;
- 您可以在执行前
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
如何使用 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 会帮助你(我使用了 ##MeterData
和 tempdb
你必须使用你实际的 table 和数据库名称)。将与源 table 中的任意数量的列一起使用。几条评论:
- 您需要
CAST
或CONVERT
所有列为一种类型(我在@p
变量中使用了nvarchar(10)
); - 我排除了
meterno
、date
、timeblock
列,因为它们在您的数据集中没有用作 参数 ; - 您可以在执行前
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