| Author |
Topic |
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-26 : 23:00:12
|
I have some data generated by an application which needs to be transformed for another application to be able to use it. Sample of my data is shown in data set, and the transformed data is shown in result set.Data set: comma seperated to show as I cannot attach snapshotTID,PN,PV1,akey,1231,akey,2341,akey,5671,pkey,3451,lkey,3212,mid,1232,mid,2232,lid,1113,pkey,1233,lkey,234Transformed data:TID,PN,PV,Group1,akey,123,11,akey,234,21,akey,567,31,pkey,345,11,pkey,345,21,pkey,345,31,lkey,321,11,lkey,321,21,lkey,321,32,mid,123,12,mid,223,22,lid,111,12,lid,111,23,pkey,123,13,lkey,234,1If you notice for TID 1, there are three PV values for PN akey and one PV value each for PN pkey and lkey. I want to insert pkey and lkey data as many times as akey, and remove the original rows, and also assign group numbers as shown in result set. So In the result set I assigned group num 1,2,3 to akey rows and copied pkey and lkey three times each with group nums as in akey.Similarly, For TID = 2, I have 2 mid rows and one lid row. The resultset would have the lid row twice with group = 1 and 2.for TID = 3 I have one value for pkey and one value for lkey. The result set would have the same data with group num 1 in both rows.This is just an example. There can be any combination, where one of the PN would have multiple PV values for same TID, and other PN rows for the same TID will have one value. The single row PN data will have to be inserted as many times as the multiple row PN is and then create sequential groups. I hope I am able to explain it. What would be the best sql way to transform this data.Thanks for your help. |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-27 : 00:20:51
|
| [code]declare @test table(TID int,PN varchar(10),PV int)insert @testvalues(1,'akey',123),(1,'akey',234),(1,'akey',567),(1,'pkey',345),(1,'lkey',321),(2,'mid',123),(2,'mid',223),(2,'lid',111),(3,'pkey',123),(3,'lkey',234);With CTEAS(SELECT *,COUNT(1) OVER (PARTITION BY TID,PN) AS CntFROM @test),CTE1AS(SELECT c.*,MaxCntFROM CTE cINNER JOIN (SELECT TID,MAX(Cnt) AS MaxCnt FROM CTE GROUP BY TID)c1 ON c1.TID = c.TID)SELECT TID,PN,PVFROM CTE1CROSS JOIN master..spt_values vWHERE v.number BETWEEN 1 AND MaxCntAND v.type='p'AND Cnt <> MaxCntUNION ALLSELECT TID,PN,PVFROM CTE1WHERE Cnt=MaxCntORDER BY TIDoutput---------------------------TID PN PV---------------------------1 akey 1231 akey 2341 akey 5671 lkey 3211 lkey 3211 lkey 3211 pkey 3451 pkey 3451 pkey 3452 lid 1112 lid 1112 mid 1232 mid 2233 lkey 2343 pkey 123[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-27 : 00:33:07
|
Simplified versiondeclare @test table(TID int,PN varchar(10),PV int)insert @testvalues(1,'akey',123),(1,'akey',234),(1,'akey',567),(1,'pkey',345),(1,'lkey',321),(2,'mid',123),(2,'mid',223),(2,'lid',111),(3,'pkey',123),(3,'lkey',234);With CTEAS(SELECT *,COUNT(1) OVER (PARTITION BY TID,PN) AS CntFROM @test),CTE1AS(SELECT c.*,1 AS Cnt1,MaxCntFROM CTE cINNER JOIN (SELECT TID,MAX(Cnt) AS MaxCnt FROM CTE GROUP BY TID)c1 ON c1.TID = c.TID UNION ALL SELECT TID,PN,PV,Cnt,Cnt1+1,MaxCnt FROM CTE1 WHERE Cnt1 + 1 < = Maxcnt AND Cnt =1)SELECT TID,PN,PVFROM CTE1ORDER BY TID,PN ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-27 : 09:33:43
|
| Thanks visakh16It inserted the right rows, but did not put the number in group column. Please help a little more.Thanks for your help. |
 |
|
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-27 : 12:12:16
|
| I figured it out to get desired result taking hints from the sql that you provided, but my sql is not so crisp as yours. Any suggestions to make it crisp to avoid all those table definitions in the beginning is welcome.Thanks. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-27 : 21:17:42
|
quote: Originally posted by learnsql123 I figured it out to get desired result taking hints from the sql that you provided, but my sql is not so crisp as yours. Any suggestions to make it crisp to avoid all those table definitions in the beginning is welcome.Thanks.
thats just for illustration you can use suggestion alone replacing tables with your actual table namesie use only this;With CTEAS(SELECT *,COUNT(1) OVER (PARTITION BY TID,PN) AS CntFROM your table here),CTE1AS(SELECT c.*,1 AS Cnt1,MaxCntFROM CTE cINNER JOIN (SELECT TID,MAX(Cnt) AS MaxCnt FROM CTE GROUP BY TID)c1 ON c1.TID = c.TID UNION ALL SELECT TID,PN,PV,Cnt,Cnt1+1,MaxCnt FROM CTE1 WHERE Cnt1 + 1 < = Maxcnt AND Cnt =1)SELECT TID,PN,PVFROM CTE1ORDER BY TID,PN ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-28 : 12:20:00
|
Here is the output that i want, by my code has table declarations, I think some of those may be avoided using ';with' clause. I tried, but could work without those table declarations. Can you please help me optimize this code, so that It works without those table declarations.Thanks.declare @AllCnt table(TID int,PN varchar(10),PV int, Cnt int)declare @Singles table (TID int,PN varchar(10),PV int, Cnt int)declare @Multi table (TID int,PN varchar(10),PV int, Cnt int)declare @singleGrp table (TID int,PN varchar(10),PV int, grp int)declare @MultiGrp table (TID int,PN varchar(10),PV int, grp int)declare @test table(TID int,PN varchar(10),PV int)insert @testvalues(1,'akey',123),(1,'akey',234),(1,'akey',567),(1,'pkey',345),(1,'lkey',321),(2,'mid',123),(2,'mid',223),(2,'lid',111),(3,'pkey',123),(3,'lkey',234);With CTEAS(SELECT *,COUNT(1) OVER (PARTITION BY TID,PN) AS CntFROM @test)Insert into @AllCntSelect * from CTE--Select * from @AllCntInsert into @SinglesSELECT TID,PN,PV, cntFROM @AllCntwhere Cnt = 1Insert into @MultiSELECT TID,PN,PV, cntFROM @AllCntwhere Cnt >1--Select * from @Singles--Select * from @Multi--=============================================================Insert into @MultiGrpSELECT TID, PN, PV,ROW_NUMBER() OVER (PARTITION BY TID,PN order by TID,PN, PV) AS grpFROM @MultiInsert into @SingleGrpSELECT S.TID, S.PN,S.PV, M.grpFrom @MultiGrp MJoin @Singles S on S.TID = M.TID--Select * from @MultiGrp--Select * from @SingleGrpSelect * from (Select * from @MultiGrp Union AllSelect * from @SingleGrp)as tmporder by TID, grp, PN |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-29 : 09:39:22
|
| whats the need of these intermediate tables?singlegrp,multigrp etcwhats the issue with my suggestion?------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-29 : 12:09:13
|
| visakh16, your script is not giving me the last column (grp). I need that.Thanks, |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-29 : 12:20:01
|
for that you dont need all these. just a small addition to my earier suggestion;With CTEAS(SELECT *,COUNT(1) OVER (PARTITION BY TID,PN) AS CntFROM your table here),CTE1AS(SELECT c.*,1 AS Cnt1,MaxCntFROM CTE cINNER JOIN (SELECT TID,MAX(Cnt) AS MaxCnt FROM CTE GROUP BY TID)c1 ON c1.TID = c.TID UNION ALL SELECT TID,PN,PV,Cnt,Cnt1+1,MaxCnt FROM CTE1 WHERE Cnt1 + 1 < = Maxcnt AND Cnt =1)SELECT TID,PN,PV,ROW_NUMBER() OVER (PARTITION BY TID,PN ORDER BY PV) AS SeqFROM CTE1ORDER BY TID,PN,Seq ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
learnsql123
Starting Member
23 Posts |
Posted - 2012-10-29 : 19:40:00
|
| Thank you. That works perfect. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-10-29 : 19:44:59
|
| welcome------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|
|
|