SQL将单列转移到多个表?

时间:2015-06-23 21:00:41

标签: sql sql-server pivot

对于SQL Server 2012:

我正在尝试通过PIVOT将我的数据规范化为第一个普通形式,然后将结果保存到表格中。 我需要有关PIVOT的帮助并将其保存到表格中。

原始数据是每日或每周生成的.xls,然后我将其批量插入temprmi$表。

原始数据结构如下 - TNUM是整个公司的唯一编号。有比这三个更多的提示文本(总共64个)。

表: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将其放入一个表中,然后我可以分成多个(如下定义),但我没有成功。

我希望得到它:

夹具表:

TNUM     Fixture   EMPID
1        506       e001
2        510       f031

表格表格:

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

2 个答案:

答案 0 :(得分:1)

您的输出看起来很好。您只需要确保在执行插入时只选择值不为null的行。

对于灯具

INSERT INTO Fixture 
SELECT * 
FROM PVTTable 
WHERE FIXTURE IS NOT NULL

修改 我看到你在某些记录上错过了这个版本。我复制了原始数据结构并使用它构建了动态数据透视表。我无法复制丢失的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

答案 1 :(得分:1)

使用查找表来保存tablename / column / prompt组合,并使用游标进行迭代,生成动态语句以将相关行插入每个表:

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以查看查找表的更多详细信息