Reputation: 25058
I have a table like
att1 att2 att3 att4
-------------------
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
What is the query to get the table as a coordinate system as:
a b val
-------
1 1 1
1 2 6
1 3 11
1 4 16
2 1 2
2 2 7
2 3 12
2 4 17
3 1 3
3 2 8
3 3 13
3 4 18
4 1 4
4 2 9
4 3 14
4 4 19
Currently I have:
select 1,att1 from data_journal_insurance_raw union all
select 2,att2 from data_journal_insurance_raw union all
select 3,att3 from data_journal_insurance_raw union all
select 4,att4 from data_journal_insurance_raw
I am missing the 'b' part how to do it?
Upvotes: 0
Views: 71
Reputation: 1065
If I understand you correctly, you want to convert the table into a table containing Row, Column and Value.
Actually, you're missing the a
part. a
represents the row, and b
the column. The following query should help you.
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
Notice that I'm casting the value column to VARCHAR(MAX)
, because I don't know what data types you have in your table. If they're all numeric, then you can drop the CAST
functions.
If you're only doing this once on a single table, then this will work fine for you. However, if you want to be able to do this on various tables, you can make SQL Server write the code for you. Here's a procedure that will do just that:
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
Upvotes: 1
Reputation: 1267
You should to have 3 column in Union
select att1 ,1,att1 from data_journal_insurance_raw union
select att1 ,2,att2 from data_journal_insurance_raw union
select att1 ,3,att3 from data_journal_insurance_raw union
select att1 ,4,att4 from data_journal_insurance_raw
Upvotes: 0