Reputation: 404
Another stupid question here regarding a SQL scenario.
Given data such as:
FieldKey DocumentKey FieldId FieldValue
1 00001c55-aab3-4df8-a07e-8eac162fa075 TITLE Mass Import 18355
2 00001c55-aab3-4df8-a07e-8eac162fa075 1 00001c55-aab3-4df8-a07e-8eac162fa075
3 00001c55-aab3-4df8-a07e-8eac162fa075 2 9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89
4 00001c55-aab3-4df8-a07e-8eac162fa075 3 18355
5 00001c55-aab3-4df8-a07e-8eac162fa075 4 94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6
6 00001c55-aab3-4df8-a07e-8eac162fa075 5 Created by C# mass import
7 00002205-00D3-4495-B65A-A7B1FD2AE7F2 TITLE Mass Import 1494780
8 00002205-00D3-4495-B65A-A7B1FD2AE7F2 1 00002205-00D3-4495-B65A-A7B1FD2AE7F2
9 00002205-00D3-4495-B65A-A7B1FD2AE7F2 2 870386312
10 00002205-00D3-4495-B65A-A7B1FD2AE7F2 3 1494780
11 00002205-00D3-4495-B65A-A7B1FD2AE7F2 4 -1929051324
13 00002342-6de0-4110-b576-fd32f96b2858 TITLE Mass Import 387008
14 00002342-6de0-4110-b576-fd32f96b2858 1 00002342-6de0-4110-b576-fd32f96b2858
15 00002342-6de0-4110-b576-fd32f96b2858 2 B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51
16 00002342-6de0-4110-b576-fd32f96b2858 3 387008
With table structure:
[FieldKey] [bigint] IDENTITY(1,1) NOT NULL,
[DocumentKey] [char](36) NOT NULL,
[FieldId] [varchar](10) NOT NULL,
[FieldValue] [varchar](255) NOT NULL
What is the best way to flip this data horizontally? Ideally:
DocumentKey TITLE 1 2 3 4 5
00001c55-aab3-4df8-a07e-8eac162fa075 mytitle val1 val2 val3 val4 val5
00002205-00D3-4495-B65A-A7B1FD2AE7F2 mytitle2 val6 val7 val8 val9
00002342-6de0-4110-b576-fd32f96b2858 mytitle3 vl10 vl11 vl12
I thought a pivot table might work and it is close, but the problem is I don't need an aggregation which is required for a SQL pivot. I just want to flip the data. The number of columns (1-5 plus TITLE in my example) could be anywhere between TITLE plus 1-30.
Maybe I'm just being dense, but any ideas would be appreciated.
Upvotes: 0
Views: 838
Reputation: 31249
I think that you are on the right track with a PIVOT
. You are going to have a aggregate on the value column. But as you say you will have 1-30 column plus the title column. That requires a dynamic pivot
Here is a suggestion (that is only for SQL Server 2005+):
Test data
CREATE TABLE Table1
(
[FieldKey] [bigint] NOT NULL,
[DocumentKey] [char](36) NOT NULL,
[FieldId] [varchar](10) NOT NULL,
[FieldValue] [varchar](255) NOT NULL
)
INSERT INTO Table1
VALUES
(1,'00001c55-aab3-4df8-a07e-8eac162fa075','TITLE','Mass Import 18355'),
(2,'00001c55-aab3-4df8-a07e-8eac162fa075','1','00001c55-aab3-4df8-a07e-8eac162fa075'),
(3,'00001c55-aab3-4df8-a07e-8eac162fa075','2','9F-2F-CF-76-27-E7-5B-C9-27-CE-23-45-68-3F-E2-89'),
(4,'00001c55-aab3-4df8-a07e-8eac162fa075','3','18355'),
(5,'00001c55-aab3-4df8-a07e-8eac162fa075','4','94-3C-84-B1-6A-AA-FD-25-F1-C0-D2-43-CD-D3-57-D6'),
(6,'00001c55-aab3-4df8-a07e-8eac162fa075','5','Created by C# mass import'),
(7,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','TITLE','Mass Import 1494780'),
(8,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','1','00002205-00D3-4495-B65A-A7B1FD2AE7F2'),
(9,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','2','870386312'),
(10,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','3','1494780'),
(11,'00002205-00D3-4495-B65A-A7B1FD2AE7F2','4','-1929051324'),
(13,'00002342-6de0-4110-b576-fd32f96b2858','TITLE','Mass Import 387008'),
(14,'00002342-6de0-4110-b576-fd32f96b2858','1','00002342-6de0-4110-b576-fd32f96b2858'),
(15,'00002342-6de0-4110-b576-fd32f96b2858','2','B0-CB-DF-ED-48-DC-C4-E8-B0-6F-1B-1D-81-2D-6D-51'),
(16,'00002342-6de0-4110-b576-fd32f96b2858','3','387008')
Find the unique columns
DECLARE @cols VARCHAR(MAX)
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Table1.FieldId
ORDER BY Table1.FieldId) AS RowNbr,
Table1.*
FROM
Table1
)
SELECT @cols=STUFF
(
(
SELECT
',' +QUOTENAME(CTE.FieldId)
FROM
CTE
WHERE
CTE.RowNbr=1
ORDER BY
LEN(CTE.FieldId) DESC,
CTE.FieldId
FOR XML PATH('')
)
,1,1,'')
We need to order so that TITLE
comes first. The FOR XML PATH
is to concat the columns.
Dynamic pivot
DECLARE @query NVARCHAR(4000)=
N'SELECT
*
FROM
(
SELECT
Table1.DocumentKey,
Table1.FieldId,
Table1.FieldValue
FROM
Table1
) AS p
PIVOT
(
MAX(FieldValue)
FOR FieldId IN('+@cols+')
) AS p'
EXECUTE(@query)
Clean up after myself (not required)
DROP TABLE Table1
Upvotes: 2
Reputation: 8818
If you're using SQL Server 2005+, you can use PIVOT operator.
select [DocumentKey], [TITLE], [1], [2], [3], [4], [5]
from (select [DocumentKey], FieldId, FieldValue from TableName) t
pivot (max(FieldValue) for FieldID in ([TITLE], [1], [2], [3], [4], [5])) as pvt
order by [DocumentKey]
You would have to add the additional columns, 6 - 30.
Upvotes: 2