SQL 将单列透视到多个表?
SQL Pivot single column to multiple tables?
对于 SQL 服务器 2012:
我正在尝试通过 PIVOT 将我的数据规范化为第一范式,然后将结果保存到 table。
我需要有关 PIVOT 的帮助并将其保存到 table.
原始数据是每日或每周生成的.xls,然后我将其批量插入到temprmi$
table.
原始数据结构如下 - TNUM 是整个公司的唯一编号。提示文字不止这三个(一共64个)
Table: temprmi$
TNUM EmpID Prompt Text TData
1 e001 fixture 506
1 e011 sheet F1234567
1 f001 cweld abcDFG
2 f031 fixture 510
2 f032 sheet H7654321
2 e001 cweld DFGabc
我尝试使用 SQL PIVOT
将它变成一个 table,然后我可以分成多个(如下定义),但我没有成功.
我希望它成为什么:
夹具 Table:
TNUM Fixture EMPID
1 506 e001
2 510 f031
sheet table:
TNUM Sheet EMPID
1 F1234567 e011
2 H7654321 f032
如有任何帮助,我们将不胜感激。
我已经添加了我的 PIVOT
查询以供参考,但它不起作用。 (下面也有输出。
DECLARE @ColumnName AS NVARCHAR(MAX)
DECLARE @DynamicPivotQuery AS nvarchar(max)
DECLARE @DynamicPivotQuery2 AS nvarchar(max)
DECLARE @DynamicPivotQuery3 AS nvarchar(max)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME([prompt text])
FROM (SELECT DISTINCT [prompt text] FROM temprmi$) AS Prompts
--select @ColumnName
SET @DynamicPivotQuery ='SELECT [trav num],[empid],' + @ColumnName
SET @DynamicPivotQuery2=' FROM [temprmi$]
PIVOT(min([TData])
FOR [Prompt Text] IN (' + @ColumnName + ')) AS PVTTable'
--select (@DynamicPivotQuery+@DynamicPivotQuery2)
set @DynamicPivotQuery3=@DynamicPivotQuery+@DynamicPivotQuery2
EXEC sp_executesql @DynamicPivotQuery3
select @DynamicPivotQuery3
输出:
TNUM EmpID Fixture sheet
1 null 506 null
1 e001 null null
1 null null F1234567
2 null 510 null
2 e001 null null
2 null null H7654321
你的输出看起来不错。您只需要确保在执行插入操作时只有 select 值不为空的行。
固定装置
INSERT INTO Fixture
SELECT *
FROM PVTTable
WHERE FIXTURE IS NOT NULL
编辑
我发现您在某些记录中缺少 empId。我复制了您的原始数据结构并使用它构建了一个动态数据透视表。我无法复制丢失的 empId 问题。也许您在问题中遗漏了一些信息。下面是一个工作示例。
CREATE TABLE #temprmi (
TNUM INT,
EmpID VARCHAR(50),
[Prompt Text] VARCHAR(100),
TData VARCHAR(100))
INSERT INTO #temprmi
(TNUM,EmpID,[Prompt Text],TData)
VALUES
(1,'e001','fixture','506'),
(1,'e011','sheet','F1234567'),
(1,'f001','cweld','abcDFG'),
(2,'f031v','fixture','510'),
(2,'f032','sheet','H7654321'),
(2,'e001','cweld','DFGabc')
DECLARE @columns VARCHAR(MAX)
SELECT @columns = COALESCE(@columns + ',', '') + CONCAT('[', [Prompt Text], ']')
FROM ( SELECT DISTINCT [Prompt Text]
FROM #temprmi) AS t
DECLARE @sql VARCHAR(MAX) =
'
SELECT TNUM, EmpID, ' + @columns + '
FROM #temprmi
PIVOT (
MIN(Tdata)
FOR [Prompt Text] IN (' + @columns + ')
) p
'
EXEC(@sql)
DROP TABLE #temprmi
使用查找 table 来保存 tablename/column/prompt 组合,并使用游标对其进行迭代,生成动态语句以将相关行插入到每个 table:
DECLARE @tableName varchar(20),
@columnName varchar(20),
@prompt varchar(20)
DECLARE @dynSQL varchar(500)
DECLARE cLookup CURSOR FOR
SELECT * FROM Lookup
OPEN cLookup
FETCH NEXT FROM cLookup
INTO @tableName, @columnName, @prompt
WHILE @@FETCH_STATUS = 0
BEGIN
SET @dynSQL = 'INSERT INTO ' + @tableName +
' SELECT TNUM, EMPID, TData AS ' + @columnName +
' FROM Input WHERE [Prompt Text] = ''' + @prompt + ''''
EXEC sp_executesql @dynSQL
FETCH NEXT FROM cLookup
INTO @tableName, @columnName, @prompt
END
CLOSE cLookup
DEALLOCATE cLookup
查看 this SQLFiddle 以查看查找的更多详细信息 table
对于 SQL 服务器 2012:
我正在尝试通过 PIVOT 将我的数据规范化为第一范式,然后将结果保存到 table。 我需要有关 PIVOT 的帮助并将其保存到 table.
原始数据是每日或每周生成的.xls,然后我将其批量插入到temprmi$
table.
原始数据结构如下 - TNUM 是整个公司的唯一编号。提示文字不止这三个(一共64个)
Table: temprmi$
TNUM EmpID Prompt Text TData
1 e001 fixture 506
1 e011 sheet F1234567
1 f001 cweld abcDFG
2 f031 fixture 510
2 f032 sheet H7654321
2 e001 cweld DFGabc
我尝试使用 SQL PIVOT
将它变成一个 table,然后我可以分成多个(如下定义),但我没有成功.
我希望它成为什么:
夹具 Table:
TNUM Fixture EMPID
1 506 e001
2 510 f031
sheet table:
TNUM Sheet EMPID
1 F1234567 e011
2 H7654321 f032
如有任何帮助,我们将不胜感激。
我已经添加了我的 PIVOT
查询以供参考,但它不起作用。 (下面也有输出。
DECLARE @ColumnName AS NVARCHAR(MAX)
DECLARE @DynamicPivotQuery AS nvarchar(max)
DECLARE @DynamicPivotQuery2 AS nvarchar(max)
DECLARE @DynamicPivotQuery3 AS nvarchar(max)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME([prompt text])
FROM (SELECT DISTINCT [prompt text] FROM temprmi$) AS Prompts
--select @ColumnName
SET @DynamicPivotQuery ='SELECT [trav num],[empid],' + @ColumnName
SET @DynamicPivotQuery2=' FROM [temprmi$]
PIVOT(min([TData])
FOR [Prompt Text] IN (' + @ColumnName + ')) AS PVTTable'
--select (@DynamicPivotQuery+@DynamicPivotQuery2)
set @DynamicPivotQuery3=@DynamicPivotQuery+@DynamicPivotQuery2
EXEC sp_executesql @DynamicPivotQuery3
select @DynamicPivotQuery3
输出:
TNUM EmpID Fixture sheet
1 null 506 null
1 e001 null null
1 null null F1234567
2 null 510 null
2 e001 null null
2 null null H7654321
你的输出看起来不错。您只需要确保在执行插入操作时只有 select 值不为空的行。
固定装置
INSERT INTO Fixture
SELECT *
FROM PVTTable
WHERE FIXTURE IS NOT NULL
编辑 我发现您在某些记录中缺少 empId。我复制了您的原始数据结构并使用它构建了一个动态数据透视表。我无法复制丢失的 empId 问题。也许您在问题中遗漏了一些信息。下面是一个工作示例。
CREATE TABLE #temprmi (
TNUM INT,
EmpID VARCHAR(50),
[Prompt Text] VARCHAR(100),
TData VARCHAR(100))
INSERT INTO #temprmi
(TNUM,EmpID,[Prompt Text],TData)
VALUES
(1,'e001','fixture','506'),
(1,'e011','sheet','F1234567'),
(1,'f001','cweld','abcDFG'),
(2,'f031v','fixture','510'),
(2,'f032','sheet','H7654321'),
(2,'e001','cweld','DFGabc')
DECLARE @columns VARCHAR(MAX)
SELECT @columns = COALESCE(@columns + ',', '') + CONCAT('[', [Prompt Text], ']')
FROM ( SELECT DISTINCT [Prompt Text]
FROM #temprmi) AS t
DECLARE @sql VARCHAR(MAX) =
'
SELECT TNUM, EmpID, ' + @columns + '
FROM #temprmi
PIVOT (
MIN(Tdata)
FOR [Prompt Text] IN (' + @columns + ')
) p
'
EXEC(@sql)
DROP TABLE #temprmi
使用查找 table 来保存 tablename/column/prompt 组合,并使用游标对其进行迭代,生成动态语句以将相关行插入到每个 table:
DECLARE @tableName varchar(20),
@columnName varchar(20),
@prompt varchar(20)
DECLARE @dynSQL varchar(500)
DECLARE cLookup CURSOR FOR
SELECT * FROM Lookup
OPEN cLookup
FETCH NEXT FROM cLookup
INTO @tableName, @columnName, @prompt
WHILE @@FETCH_STATUS = 0
BEGIN
SET @dynSQL = 'INSERT INTO ' + @tableName +
' SELECT TNUM, EMPID, TData AS ' + @columnName +
' FROM Input WHERE [Prompt Text] = ''' + @prompt + ''''
EXEC sp_executesql @dynSQL
FETCH NEXT FROM cLookup
INTO @tableName, @columnName, @prompt
END
CLOSE cLookup
DEALLOCATE cLookup
查看 this SQLFiddle 以查看查找的更多详细信息 table