我有一个包含多个列的表:
CREATE TABLE [dbo].[MyTable](
[ValueID] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[RealValue] [float] NOT NULL
) ON PRIMARY
+---------+----------------------+----------+
| ValueID | Timestamp |RealValue |
+---------+----------------------+----------+
| 123 | 3/1/2018 12:00:49 AM | 54.1 |
| 123 | 3/1/2018 12:01:49 AM | 55.1 |
| 123 | 3/1/2018 12:02:49 AM | 56.1 |
| 123 | 3/1/2018 12:03:49 AM | 57.1 |
| 123 | 3/1/2018 12:04:49 AM | 58.1 |
| 876 | 3/1/2018 12:00:49 AM | 1.0 |
| 876 | 3/1/2018 12:01:49 AM | 1.1 |
| 876 | 3/1/2018 12:02:49 AM | 1.2 |
| 876 | 3/1/2018 12:03:49 AM | 1.3 |
| 876 | 3/1/2018 12:04:49 AM | 1.4 |
| 63 | 3/1/2018 12:00:49 AM | 300.0 |
| 63 | 3/1/2018 12:01:49 AM | 300.5 |
| 63 | 3/1/2018 12:02:49 AM | 301.0 |
| 63 | 3/1/2018 12:03:49 AM | 301.5 |
| 63 | 3/1/2018 12:04:49 AM | 302.0 |
+---------+----------------------+----------+
我需要将此表拆分为“每列值列”结构:
+----------------------+----------+----------+----------+
| Timestamp | 123 | 876 | 63 |
+----------------------+----------+----------+----------+
| 3/1/2018 12:00:49 AM | 54.1 | 1.0 | 300.0 |
| 3/1/2018 12:01:49 AM | 55.1 | 1.1 | 300.5 |
| 3/1/2018 12:02:49 AM | 56.1 | 1.2 | 301.0 |
| 3/1/2018 12:03:49 AM | 57.1 | 1.3 | 301.5 |
| 3/1/2018 12:04:49 AM | 58.1 | 1.4 | 302.0 |
+----------------------+----------+----------+----------+
这可以用SQL,还是更适合脚本?
如:
SELECT DISTINCT [ValueID] FROM [db].[dbo].[MyTable]
// ...Build a hash of distinct values in the script...
CREATE TABLE [dbo].[NewTable](
[123] int NOT NULL,
[876] int NOT NULL,
[63] int NOT NULL
...
) ON PRIMARY
// ...Loop through hash and populate each column with a separate query...
该表相当大(2600万行),并且有大约500个不同的[ValueID]
值,这些值将成为目标表中的列。
答案 0 :(得分:0)
您可以使用pivot
声明。
如果您有一定数量的ValueID
值,您可以编写这样的查询(否则您应该使用动态解决方案来生成所有输出列):
if OBJECT_ID('MyTable') is null
CREATE TABLE [dbo].[MyTable](
[ValueID] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[RealValue] [float] NOT NULL
)
insert into [dbo].[MyTable]
select 123 ,'20180301 12:00:49',54.1
union all select 123 ,'20180301 12:01:49',55.1
union all select 123 ,'20180301 12:02:49',56.1
union all select 123 ,'20180301 12:03:49',57.1
union all select 123 ,'20180301 12:04:49',58.1
union all select 876 ,'20180301 12:00:49',1.0
union all select 876 ,'20180301 12:01:49',1.1
union all select 876 ,'20180301 12:02:49',1.2
union all select 876 ,'20180301 12:03:49',1.3
union all select 876 ,'20180301 12:04:49',1.4
union all select 63 ,'20180301 12:00:49',300.0
union all select 63 ,'20180301 12:01:49',300.5
union all select 63 ,'20180301 12:02:49',301.0
union all select 63 ,'20180301 12:03:49',301.5
union all select 63 ,'20180301 12:04:49',302.0
select piv.*
from
(
select ValueID,Timestamp,RealValue
from [dbo].[MyTable]
) src
pivot
(
max(realValue)
for valueid in ([123], [876], [63]) -- If you have other valueids add them here
) piv
此查询的结果:
如果您需要动态查询来自动创建所有ValueId
值的所有列,您可以使用动态SQL,但要注意此方法的安全问题(SQL注入等)!
以下示例脚本可动态生成包含ValueID
的所有列的查询:
if OBJECT_ID('MyTableDyn') is null
CREATE TABLE [dbo].[MyTableDyn](
[ValueID] [int] NOT NULL,
[Timestamp] [datetime] NOT NULL,
[RealValue] [float] NOT NULL
)
insert into [dbo].[MyTableDyn]
select 123 ,'20180301 12:00:49',54.1
union all select 123 ,'20180301 12:01:49',55.1
union all select 123 ,'20180301 12:02:49',56.1
union all select 123 ,'20180301 12:03:49',57.1
union all select 123 ,'20180301 12:04:49',58.1
union all select 876 ,'20180301 12:00:49',1.0
union all select 876 ,'20180301 12:01:49',1.1
union all select 876 ,'20180301 12:02:49',1.2
union all select 876 ,'20180301 12:03:49',1.3
union all select 876 ,'20180301 12:04:49',1.4
union all select 63 ,'20180301 12:00:49',300.0
union all select 63 ,'20180301 12:01:49',300.5
union all select 63 ,'20180301 12:02:49',301.0
union all select 63 ,'20180301 12:03:49',301.5
union all select 63 ,'20180301 12:04:49',302.0
union all select 99 ,'20180301 12:00:49',900.0
union all select 99 ,'20180301 12:01:49',900.5
union all select 99 ,'20180301 12:02:49',901.0
union all select 99 ,'20180301 12:03:49',901.5
union all select 99 ,'20180301 12:04:49',902.0
declare @script nvarchar(max)=''
declare @ids nvarchar(max)=''
select @ids = @ids + ', ['+ cast([ValueID] as varchar(max)) + ']'
from [dbo].[MyTableDyn]
group by [ValueID]
set @ids = RIGHT(@ids, len(@ids)-2)
set @script = @script + 'select piv.*'
set @script = @script + ' from'
set @script = @script + ' ( '
set @script = @script + ' select ValueID,Timestamp,RealValue'
set @script = @script + ' from [dbo].[MyTableDyn] '
set @script = @script + ' ) src '
set @script = @script + ' pivot '
set @script = @script + ' ('
set @script = @script + ' max(realValue) '
set @script = @script + ' for valueid in (' + @ids +') '
set @script = @script + ' ) piv '
exec (@script)
以下是结果(如您所见,出现ID为99的新列):