SQL表转换

时间:2014-09-12 09:24:00

标签: sql-server

我有两张桌子:

1)保存输入字段名称和ID

2)表保存数据是在字段中写的。

在示例表(2)中保存两条记录。我想转换成3)表。但我想动态地做,因为将来我会添加更多的字段名称?

1) 
+-------------------+-----------------+
| UserDefinedFieldId| FieldTitle      |
+-------------------+-----------------+
| 266               | Change at       |
| 267               | User name       |
| 268               | Message         |
+-------------------+-----------------+
2)
+-------------------+-----------------+-------------------+
| UserDefinedFieldId| UserDefinedRowId|FieldValue         |
+-------------------+-----------------+-------------------+
| 266               | 1               |2014-09-01         |
| 266               | 2               |2014-09-02         |
| 267               | 1               |my name            |
| 267               | 2               |another name       |
| 268               | 1               |My message         |
| 268               | 2               |Another message    |
+-------------------+-----------------+-------------------+
3)
+-------------------+-----------------+-------------------+
| Change at         | User name       |Message            |
+-------------------+-----------------+-------------------+
| 2014-09-01        | my name         |My message         |
| 2014-09-04        | another name    |Another message    |
+-------------------+-----------------+-------------------+

1 个答案:

答案 0 :(得分:2)

通过使用动态sql构建要与pivot一起使用的列/值集来实现此目的。 如果表是名称​​ Table1 Table2 ,则此查询应该执行您想要的操作:

DECLARE @SQL AS NVARCHAR(MAX)
DECLARE @Cols AS NVARCHAR(MAX)
DECLARE @Values AS NVARCHAR(MAX)

SELECT 
    @Cols = ISNULL(@Cols + ',','') + QUOTENAME(FieldTitle),
    @Values= ISNULL(@Values + ',','') 
    + CHAR(13) + CHAR(9) 
    + 'MAX(' + QUOTENAME(FieldTitle) + ') AS '+ QUOTENAME(FieldTitle)
FROM (SELECT DISTINCT FieldTitle FROM Table1) AS Source

SET @SQL = N'
SELECT 
    UserDefinedRowId, ' 
    + @Values +' 
FROM (
    SELECT 
        t2.UserDefinedRowId, 
        t1.UserDefinedFieldId, 
        t2.FieldValue, 
        t1.FieldTitle 
    FROM Table1 t1
    INNER JOIN Table2 t2 ON t1.UserDefinedFieldId = t2.UserDefinedFieldId
    ) a
PIVOT(
    MAX(FieldValue)
    FOR FieldTitle IN (' + @Cols + ')
) AS [Pivot] 
GROUP BY UserDefinedRowId'

--PRINT @SQL -- you can use this line to print the generated sql statement.
EXEC (@SQL)

我确实包含了用于分组的UserDefinedRowId列,如果您不想要,请将其删除。

Sample SQL Fiddle

Another SQL Fiddle允许选择日期范围。