tsql - Complicated irregular pivot in SQL Server 2012 -


i have 2 tables:

a (column1, column2, column3) b (column6, column7, column8) 

a.column1 foreign key in b.column6.

one row table a matches 3 rows in table b, 5, 1.... no definite count of returned rows.

i have business requirement flip corresponding columns in table b 1 row.. this:

a.column1, a.column2, a.column3, b.column7, b.column8, b.column7, b.column8 a.column1, a.column2, a.column3, b.column7, b.column8 a.column1, a.column2, a.column3, b.column7, b.column8, b.column7, b.column8, b.column7, b.column8 a.column1, a.column2, a.column3, b.column7, b.column8, b.column7, b.column8, b.column7, b.column8b.column7, b.column8, b.column7, b.column8   

you see , number of columns in each row table 3... table b, might have variable number of columns.... , column7 , column8 have repeated appear in order.

how can this? thanks.

it sounds going need unpivot , pivot data. if have unknown number of values have use dynamic sql first suggest writing hard-code or static version of query first, convert dynamic sql.

the process unpivot data going take multiple columns in tableb , convert multiple rows. since using sql server 2012 can use cross apply unpivot data:

select column1, column2, column3,   col = col + '_' + cast(seq varchar(10)),  value (   select a.column1, a.column2, a.column3,     b.column6, b.column7, b.column8,     row_number() over(partition a.column1                       order a.column1) seq   tablea   inner join tableb b     on a.column1 = b.column6 ) d cross apply (   select 'column6', column6 union   select 'column7', column7 union   select 'column8', column8 ) c (col, value); 

see sql fiddle demo. give result similar to:

| column1 | column2 | column3 |       col | value | |       1 |       2 |       3 | column6_1 |     1 | |       1 |       2 |       3 | column7_1 |    18 | |       1 |       2 |       3 | column8_1 |    56 | |       1 |       2 |       3 | column6_2 |     1 | |       1 |       2 |       3 | column7_2 |    25 | |       1 |       2 |       3 | column8_2 |    89 | 

as can see have multiple rows can apply pivot function to. pivot code be:

select column1, column2, column3,   column6_1, column7_1, column8_1,   column6_2, column7_2, column8_2,   column6_3, column7_3, column8_3 (   select column1, column2, column3,     col = col + '_' + cast(seq varchar(10)),     value     (     select a.column1, a.column2, a.column3,       b.column6, b.column7, b.column8,       row_number() over(partition a.column1                         order a.column1) seq     tablea     inner join tableb b       on a.column1 = b.column6   ) d   cross apply   (     select 'column6', column6 union     select 'column7', column7 union     select 'column8', column8   ) c (col, value) ) src pivot (   max(value)   col in (column6_1, column7_1, column8_1,               column6_2, column7_2, column8_2,               column6_3, column7_3, column8_3) ) piv; 

see sql fiddle demo. since stated might have unknown or dynamic number of entries in tableb need use dynamic sql. generate sql string executed final result:

declare @cols nvarchar(max),     @query  nvarchar(max)  select @cols = stuff((select ',' + quotename(col +'_'+cast(seq varchar(10)))                                          (                       select row_number() over(partition column6                                                 order column6) seq                       tableb                     ) t                     cross apply                     (                       select 'column6', 1 union                       select 'column7', 2 union                       select 'column8', 3                     ) c (col, so)                     group col, so, seq                     order seq,             xml path(''), type             ).value('.', 'nvarchar(max)')          ,1,1,'')  set @query = 'select column1, column2, column3,' + @cols + '                          (               select column1, column2, column3,                 col = col + ''_'' + cast(seq varchar(10)),                 value                             (                 select a.column1, a.column2, a.column3,                   b.column6, b.column7, b.column8,                   row_number() over(partition a.column1                                     order a.column1) seq                 tablea                 inner join tableb b                   on a.column1 = b.column6               ) d               cross apply               (                 select ''column6'', column6 union                 select ''column7'', column7 union                 select ''column8'', column8               ) c (col, value)             ) x             pivot              (                 max(value)                 col in (' + @cols + ')             ) p '  execute sp_executesql @query; 

see sql fiddle demo. both versions give result:

| column1 | column2 | column3 | column6_1 | column7_1 | column8_1 | column6_2 | column7_2 | column8_2 | column6_3 | column7_3 | column8_3 | |       1 |       2 |       3 |         1 |        18 |        56 |         1 |        25 |        89 |    (null) |    (null) |    (null) | |       2 |       4 |       6 |         2 |        78 |       245 |    (null) |    (null) |    (null) |    (null) |    (null) |    (null) | |       3 |       8 |       9 |         3 |        10 |        15 |         3 |        45 |       457 |         3 |        89 |        50 | 

Comments

Popular posts from this blog

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

html - How to style widget with post count different than without post count -

url rewriting - How to redirect a http POST with urlrewritefilter -