April 9, 2008 at 11:52 am
/*
Using SQL 2005.
I need to return denormalized data from this sample data:
*/
DECLARE @Tmp TABLE (
GroupColumnA varchar(6),
GroupColumnB varchar(6) NULL,
GroupColumnC varchar(13),
DetailColumnA varchar(15),
DetailColumnB varchar(30))
insert into @Tmp
select '123456', '','1111223334444', 'AB1984', 'Remarks1' UNION
select '123456', '','1111223334444', 'AB7458', 'Remarks2' UNION
select '123456', '','1111223334444', 'AB7461', 'Remarks3' UNION
select '123456', '','1111223334444', 'AB8461', 'Remarks4' UNION
select '123456', '','4444332221111', 'AB1234', 'Remarks5' UNION
select '123456', '','4444332221111', 'AB4567', 'Remarks6' UNION
select '123456', '','4444332221111', 'AB8574', 'Remarks7' UNION
select '123456', '','4444332221111', 'AB9876', 'Remarks8' UNION
select '147852', '','2222334445555', 'SS8000-1', 'Remarks9' UNION
select '147852', '','2222334445555', 'SS8000-2', 'Remarks10' UNION
select '147852', '','2222334445555', 'SS8000-3', 'Remarks11' UNION
select '147852', '','2222334445555', 'SS8000-4', 'Remarks12'
select * from @Tmp
-- data going into @Tmp will be sorted by the first four columns.
-- Results should look like:
DECLARE @tmp1 TABLE (
GroupColumnA varchar(6),
GroupColumnB varchar(6) NULL,
GroupColumnC varchar(13),
DetailColumnA1 varchar(15),
DetailColumnB1 varchar(30),
DetailColumnA2 varchar(15),
DetailColumnB2 varchar(30),
DetailColumnA3 varchar(15),
DetailColumnB3 varchar(30))
insert into @tmp1
select '123456', NULL, '1111223334444', 'AB1984', 'Remarks1', 'AB7458',
'Remarks2', 'AB7461', 'Remarks3' UNION
select '123456', NULL, '1111223334444', 'AB8461', 'Remarks4', NULL, NULL,
NULL, NULL UNION
select '123456', NULL, '4444332221111', 'AB1234', 'Remarks5', 'AB4567',
'Remarks6', 'AB8574', 'Remarks7' UNION
select '123456', NULL, '4444332221111', 'AB9876', 'Remarks8', NULL, NULL,
NULL, NULL UNION
select '147852', NULL, '2222334445555', 'SS8000-1', 'Remarks9', 'SS8000-2',
'Remarks10', 'SS8000-3', 'Remarks11' UNION
select '147852', NULL, '2222334445555', 'SS8000-4', 'Remarks12', NULL, NULL,
NULL, NULL
select * from @tmp1
/*
where the first 3 rows of @Tmp have the DetailColumns filled in for @tmp1.
This will cause the DetailColumnA to be in ascending order from left to
right, top to bottom in @tmp1 DetailColumnA1/A2/A3. At any change in any of
the three GroupColumn's, this should start all over with the next
DetailColumnA going into DetailColumnA1.
I'd like to do this in a set-based solution, if possible.
Thanks,
Wayne
*/
Wayne
Microsoft Certified Master: SQL Server 2008
Author - SQL Server T-SQL Recipes
April 9, 2008 at 2:03 pm
Have you looked at Pivot and Unpivot for this?
- Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
Property of The Thread
"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
April 9, 2008 at 3:09 pm
GSquared (4/9/2008)
Have you looked at Pivot and Unpivot for this?
Yes. Pivot performs an aggregrate on one grouping column and makes a column for each row. Not quite what I need.
I have three grouping columns, multiple detail columns, and only want to go up to three (sets of) detail columns wide. And I'm not doing an aggregrate.
Wayne
Microsoft Certified Master: SQL Server 2008
Author - SQL Server T-SQL Recipes
April 10, 2008 at 7:31 am
Pivot can be used that way, you just have to trick it.
Max(ID) = ID
If you aggregate on the column you group by, you end up with the column exactly as it is.
If you don't want to mess around with that, then what you do is an "old-style pivot". There are a couple of discussions on how to do that on this page. If you do a search for those terms, you should find them.
- Gus "GSquared", RSVP, OODA, MAP, NMVP, FAQ, SAT, SQL, DNA, RNA, UOI, IOU, AM, PM, AD, BC, BCE, USA, UN, CF, ROFL, LOL, ETC
Property of The Thread
"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
April 10, 2008 at 7:57 am
Try this
with cte as (
select GroupColumnA,
GroupColumnB,
GroupColumnC,
DetailColumnA,
DetailColumnB,
(row_number() over(partition by GroupColumnA,GroupColumnB,GroupColumnC
order by DetailColumnA)-1)%3 as rnmod,
(row_number() over(partition by GroupColumnA,GroupColumnB,GroupColumnC
order by DetailColumnA)-1)/3 as rndiv
from @Tmp
)
select GroupColumnA,
GroupColumnB,
GroupColumnC,
max(case when rnmod=0 then DetailColumnA end) as DetailColumnA1,
max(case when rnmod=0 then DetailColumnB end) as DetailColumnB1,
max(case when rnmod=1 then DetailColumnA end) as DetailColumnA2,
max(case when rnmod=1 then DetailColumnB end) as DetailColumnB2,
max(case when rnmod=2 then DetailColumnA end) as DetailColumnA3,
max(case when rnmod=2 then DetailColumnB end) as DetailColumnB3
from cte
group by GroupColumnA,GroupColumnB,GroupColumnC,rndiv
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537April 14, 2008 at 6:40 am
Thanks Mark, this works really nice.
Mark (4/10/2008)
Try this
with cte as (
select GroupColumnA,
GroupColumnB,
GroupColumnC,
DetailColumnA,
DetailColumnB,
(row_number() over(partition by GroupColumnA,GroupColumnB,GroupColumnC
order by DetailColumnA)-1)%3 as rnmod,
(row_number() over(partition by GroupColumnA,GroupColumnB,GroupColumnC
order by DetailColumnA)-1)/3 as rndiv
from @Tmp
)
select GroupColumnA,
GroupColumnB,
GroupColumnC,
max(case when rnmod=0 then DetailColumnA end) as DetailColumnA1,
max(case when rnmod=0 then DetailColumnB end) as DetailColumnB1,
max(case when rnmod=1 then DetailColumnA end) as DetailColumnA2,
max(case when rnmod=1 then DetailColumnB end) as DetailColumnB2,
max(case when rnmod=2 then DetailColumnA end) as DetailColumnA3,
max(case when rnmod=2 then DetailColumnB end) as DetailColumnB3
from cte
group by GroupColumnA,GroupColumnB,GroupColumnC,rndiv
Wayne
Microsoft Certified Master: SQL Server 2008
Author - SQL Server T-SQL Recipes
Viewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply