如果我理解正确,您希望将表格转换为包含行、列和值的表格。
实际上,你错过了这个a
部分。a
代表行和b
列。以下查询应该对您有所帮助。
WITH cte AS (SELECT ROW_NUMBER() OVER (ORDER BY att1) AS a, * FROM data_journal_insurance_raw)
SELECT a, 1 as b, CAST(att1 AS VARCHAR(MAX)) FROM cte UNION ALL
SELECT a, 2 as b, CAST(att2 AS VARCHAR(MAX)) FROM cte UNION ALL
SELECT a, 3 as b, CAST(att3 AS VARCHAR(MAX)) FROM cte UNION ALL
SELECT a, 4 as b, CAST(att4 AS VARCHAR(MAX)) FROM cte
ORDER BY a, b
请注意,我将 value 列转换为VARCHAR(MAX)
,因为我不知道您的表中有哪些数据类型。如果它们都是数字,那么您可以删除这些CAST
函数。
如果你只在一张桌子上这样做一次,那么这对你来说很好。但是,如果您希望能够在各种表上执行此操作,您可以让 SQL Server 为您编写代码。这是一个可以做到这一点的程序:
CREATE PROCEDURE usp_Coordinate_table(@TableName NVARCHAR(200)) AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
WITH cte AS (SELECT TOP 1 c.name FROM sys.columns c, sys.objects o WHERE c.object_id = o.object_id AND o.name = @TableName)
SELECT @sql = 'WITH RowData AS (SELECT ROW_NUMBER() OVER (ORDER BY '+name+') AS RowNum, * FROM '+@TableName+') ' FROM cte;
WITH ColData AS (SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS ColNum, c.name
FROM sys.columns c, sys.objects o WHERE c.object_id = o.object_id AND o.name = @TableName)
SELECT @sql = @sql + 'SELECT RowNum, '+CAST(c.ColNum AS VARCHAR)+' AS ColNum, CAST('+c.name+' AS VARCHAR(MAX)) AS Value FROM RowData UNION ALL '
FROM ColData c
SET @sql = SUBSTRING(@sql, 1, LEN(@sql) - 10) + ' ORDER BY RowNum, ColNum'
EXEC sp_executesql @sql
END