我有一个存储在SQL Server数据库中的表,其中包含用户ID,产品名称和按行存储在列中的值。这几周的列名称如下所示" trx_2015#08#07"并且该周的值存储在每列中:
UserId, ProductName, trx_2015#08#07, trx_2015#08#014, trx_2015#08#21
我想清理那些列名(我不能改变表格)只是周值(2015-08-07),然后将数据转换为这种格式:
userID, ProductName, Week, Value
对最简单的方法有任何想法吗?
答案 0 :(得分:1)
SQL Server提供了一种使用UNPIVOT
relational operator按照您的意愿操作数据的方法。以下是除了动态获取列名之外如何实现此目的的示例(理想情况下,我们不希望每次添加列时都更新查询)。
CREATE TABLE tbl (
UserId INT,
ProductName NVARCHAR(1000),
[trx_2015#08#07] INT,
[trx_2015#08#014] INT,
[trx_2015#08#21] INT
);
INSERT INTO tbl(UserId, ProductName, [trx_2015#08#07], [trx_2015#08#014], [trx_2015#08#21])
VALUES (1, 'Product #1', 123, 456, 789);
trx
列名称我们需要将trx
colmn名称的聚合连接传递给UNPIVOT
关系overator的IN
子句。
SELECT STUFF((SELECT ',' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'tbl'
AND COLUMN_NAME LIKE 'trx_%'
FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')
最终,我们希望查询看起来像这样:
SELECT UserId, ProductName, Value, trx
FROM tbl
UNPIVOT(
Value FOR trx IN ([trx_2015#08#014],[trx_2015#08#07],[trx_2015#08#21])
) AS unpvt
查询必须在SQL中动态构建,因为此处的IN
子句不能接受结果集。
<强>查询:强>
DECLARE @SQLString NVARCHAR(MAX);
SET @SQLString = CONCAT(
'SELECT UserId, ProductName, Value, trx FROM tbl UNPIVOT(Value FOR trx IN (',
(SELECT STUFF((SELECT ',' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'tbl'
AND COLUMN_NAME LIKE 'trx_%'
FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')),
')) AS unpvt'
);
EXEC(@SQLString);
结果集:
UserId ProductName Value trx
1 Product #1 456 trx_2015#08#014
1 Product #1 123 trx_2015#08#07
1 Product #1 789 trx_2015#08#21