You have a bit of a mess here because you want to convert multiple columns with multiple rows to more columns, and in addition, you will need to use different aggregates for each, because some of them you need SUM and others, you will have to use MAX or MIN (in string / dates).
Instead of diving directly into the dynamic version of sql, you should always try to get the correct logic using a smaller version of the static query. This makes working with dynamic SQL a lot easier, in my opinion, because you have no idea what to do or what does not work correctly.
First, I start with a query that gets the total amount of each item needed for SUM.
select ebeln, ebelp, c_Meaning, vgabe, dmbtr = cast(sum(dmbtr) over(partition by ebeln, ebelp, vgabe) as varchar(50)), menge = cast(sum(menge) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_count = cast(sum(c_count) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_EBKE_BLDAT_First = cast(c_EBKE_BLDAT_First as varchar(50)), c_EKBE_BUDAT_First = cast(c_EKBE_BUDAT_First as varchar(50)), c_EBKE_BLDAT_Last = cast(c_EBKE_BLDAT_Last as varchar(50)), c_EKBE_BUDAT_Last = cast(c_EKBE_BUDAT_Last as varchar(50)) from preEKBE
See SQL Fiddle with Demo . This gets the values of everything you need in the end result, because you get the amount for a combination of ebeln , ebelp and vgabe . You will see that I also included all the values in the same data type - this is necessary for the next step - univot. Since all data will be stored in one column, they need the same data types.
select d.ebeln, d.ebelp, new_col = c.orig_col + '_' + cast(d.vgabe as varchar(2)), c.value from ( select ebeln, ebelp, c_Meaning, vgabe, dmbtr = cast(sum(dmbtr) over(partition by ebeln, ebelp, vgabe) as varchar(50)), menge = cast(sum(menge) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_count = cast(sum(c_count) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_EBKE_BLDAT_First = cast(c_EBKE_BLDAT_First as varchar(50)), c_EKBE_BUDAT_First = cast(c_EKBE_BUDAT_First as varchar(50)), c_EBKE_BLDAT_Last = cast(c_EBKE_BLDAT_Last as varchar(50)), c_EKBE_BUDAT_Last = cast(c_EKBE_BUDAT_Last as varchar(50)) from preEKBE ) d cross apply ( select 'c_Meaning', c_Meaning union all select 'c_MENGE', menge union all select 'c_DMBTR', dmbtr union all select 'c_count', c_count union all select 'c_EBKE_BLDAT_First', c_EBKE_BLDAT_First union all select 'c_EKBE_BUDAT_First', c_EKBE_BUDAT_First union all select 'c_EBKE_BLDAT_Last', c_EBKE_BLDAT_Last union all select 'c_EKBE_BUDAT_Last', c_EKBE_BUDAT_Last ) c (orig_col, value)
See SQL Fiddle with Demo . You now have data that looks like this:
| EBELN | EBELP | NEW_COL | VALUE | |------------|-------|----------------------|-----------------------------| | 3000000004 | 1 | c_Meaning_1 | Wareneingang | | 3000000004 | 1 | c_MENGE_1 | 1 | | 3000000004 | 1 | c_DMBTR_1 | 27.95 | | 3000000004 | 1 | c_count_1 | 1 | | 3000000004 | 1 | c_EBKE_BLDAT_First_1 | 19.12.2000 | | 3000000004 | 1 | c_EKBE_BUDAT_First_1 | 19.12.2000 |
Finally, you would apply the PIVOT function:
select ebeln, ebelp, c_Meaning_1, c_MENGE_1, c_DMBTR_1, c_count_1, c_EBKE_BLDAT_First_1, c_EKBE_BUDAT_First_1, c_EBKE_BLDAT_Last_1, c_EKBE_BUDAT_Last_1 from ( select d.ebeln, d.ebelp, new_col = c.orig_col + '_' + cast(d.vgabe as varchar(2)), c.value from ( select ebeln, ebelp, c_Meaning, vgabe, dmbtr = cast(sum(dmbtr) over(partition by ebeln, ebelp, vgabe) as varchar(50)), menge = cast(sum(menge) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_count = cast(sum(c_count) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_EBKE_BLDAT_First = cast(c_EBKE_BLDAT_First as varchar(50)), c_EKBE_BUDAT_First = cast(c_EKBE_BUDAT_First as varchar(50)), c_EBKE_BLDAT_Last = cast(c_EBKE_BLDAT_Last as varchar(50)), c_EKBE_BUDAT_Last = cast(c_EKBE_BUDAT_Last as varchar(50)) from preEKBE ) d cross apply ( select 'c_Meaning', c_Meaning union all select 'c_MENGE', menge union all select 'c_DMBTR', dmbtr union all select 'c_count', c_count union all select 'c_EBKE_BLDAT_First', c_EBKE_BLDAT_First union all select 'c_EKBE_BUDAT_First', c_EKBE_BUDAT_First union all select 'c_EBKE_BLDAT_Last', c_EBKE_BLDAT_Last union all select 'c_EKBE_BUDAT_Last', c_EKBE_BUDAT_Last ) c (orig_col, value) ) src pivot ( max(value) for new_col in (c_Meaning_1, c_MENGE_1, c_DMBTR_1, c_count_1, c_EBKE_BLDAT_First_1, c_EKBE_BUDAT_First_1, c_EBKE_BLDAT_Last_1, c_EKBE_BUDAT_Last_1) ) piv;
See SQL Fiddle with Demo .
Now that you have working logic, you can convert it to dynamic sql:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(col + '_' + cast(VGABE as varchar(2))) from preEKBE t cross apply ( select 'c_meaning', 0 union all select 'c_DMBTR', 1 union all select 'c_MENGE', 2 union all select 'c_COUNT', 3 union all select 'c_EBKE_BLDAT_FIRST', 4 union all select 'c_EKBE_BUDAT_FIRST', 5 union all select 'c_EBKE_BLDAT_LAST', 6 union all select 'c_EKBE_BUDAT_LAST', 7 ) c (col, so) group by col, so, VGABE order by VGABE, so FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT EBELN, EBELP, ' + @cols + N' from ( select d.ebeln, d.ebelp, new_col = c.orig_col + ''_'' + cast(d.vgabe as varchar(2)), c.value from ( select ebeln, ebelp, c_Meaning, vgabe, dmbtr = cast(sum(dmbtr) over(partition by ebeln, ebelp, vgabe) as varchar(50)), menge = cast(sum(menge) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_count = cast(sum(c_count) over(partition by ebeln, ebelp, vgabe) as varchar(50)), c_EBKE_BLDAT_First = cast(c_EBKE_BLDAT_First as varchar(50)), c_EKBE_BUDAT_First = cast(c_EKBE_BUDAT_First as varchar(50)), c_EBKE_BLDAT_Last = cast(c_EBKE_BLDAT_Last as varchar(50)), c_EKBE_BUDAT_Last = cast(c_EKBE_BUDAT_Last as varchar(50)) from preEKBE ) d cross apply ( select ''c_meaning'', d.c_meaning union all select ''c_MENGE'', d.MENGE union all select ''c_DMBTR'', d.DMBTR union all select ''c_COUNT'', d.c_COUNT union all select ''c_EBKE_BLDAT_First'', d.c_EBKE_BLDAT_First union all select ''c_EKBE_BUDAT_First'', d.c_EKBE_BUDAT_First union all select ''c_EBKE_BLDAT_Last'', d.c_EBKE_BLDAT_Last union all select ''c_EKBE_BUDAT_Last'', d.c_EKBE_BUDAT_Last ) c (orig_col, value) ) x pivot ( max(value) for new_col in (' + @cols + N') ) p order by EBELN , EBELP' exec sp_executesql @query;
See SQL Fiddle with Demo . This gives the final result:
| EBELN | EBELP | C_MEANING_1 | C_DMBTR_1 | C_MENGE_1 | C_COUNT_1 | C_EBKE_BLDAT_FIRST_1 | C_EKBE_BUDAT_FIRST_1 | C_EBKE_BLDAT_LAST_1 | C_EKBE_BUDAT_LAST_1 | C_MEANING_2 | C_DMBTR_2 | C_MENGE_2 | C_COUNT_2 | C_EBKE_BLDAT_FIRST_2 | C_EKBE_BUDAT_FIRST_2 | C_EBKE_BLDAT_LAST_2 | C_EKBE_BUDAT_LAST_2 | C_MEANING_6 | C_DMBTR_6 | C_MENGE_6 | C_COUNT_6 | C_EBKE_BLDAT_FIRST_6 | C_EKBE_BUDAT_FIRST_6 | C_EBKE_BLDAT_LAST_6 | C_EKBE_BUDAT_LAST_6 | C_MEANING_8 | C_DMBTR_8 | C_MENGE_8 | C_COUNT_8 | C_EBKE_BLDAT_FIRST_8 | C_EKBE_BUDAT_FIRST_8 | C_EBKE_BLDAT_LAST_8 | C_EKBE_BUDAT_LAST_8 | C_MEANING_9 | C_DMBTR_9 | C_MENGE_9 | C_COUNT_9 | C_EBKE_BLDAT_FIRST_9 | C_EKBE_BUDAT_FIRST_9 | C_EBKE_BLDAT_LAST_9 | C_EKBE_BUDAT_LAST_9 | |------------|-------|--------------|-----------|-----------|-----------|----------------------|----------------------|---------------------|---------------------|------------------|-----------|-----------|-----------|----------------------|----------------------|---------------------|---------------------|-----------------------------|-----------|-----------|-----------|----------------------|----------------------|---------------------|---------------------|-------------------------|-----------|-----------|-----------|----------------------|----------------------|---------------------|---------------------|--------------------------|-----------|-----------|-----------|----------------------|----------------------|---------------------|---------------------| | 3000000004 | 1 | Wareneingang | 27.95 | 1 | 1 | 19.12.2000 | 19.12.2000 | 19.12.2000 | 19.12.2000 | Rechnungseingang | 27.95 | 1 | 1 | 19.12.2000 | 21.12.2000 | 19.12.2000 | 21.12.2000 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | | 3000000004 | 2 | Wareneingang | 10.95 | 1 | 1 | 19.12.2000 | 19.12.2000 | 19.12.2000 | 19.12.2000 | Rechnungseingang | 10.95 | 1 | 1 | 19.12.2000 | 21.12.2000 | 19.12.2000 | 21.12.2000 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | | 4500008499 | 10 | Wareneingang | 268.43 | 1 | 1 | 27.03.2000 | 27.03.2000 | 27.03.2000 | 27.03.2000 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | Leistungserfassungsblatt | 268.43 | 1 | 1 | 27.03.2000 | 27.03.2000 | 27.03.2000 | 27.03.2000 | | 4500010470 | 10 | Wareneingang | 0.00 | 4604 | 12 | 07.02.2001 | 07.02.2001 | 07.02.2001 | 07.02.2001 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) | Warenausgabe für Umlagerung | 2117.84 | 4604 | 12 | 07.02.2001 | 07.02.2001 | 07.02.2001 | 07.02.2001 | Lieferung zu Umlagerung | 0.00 | 4604 | 12 | 01.01.1900 | 07.02.2001 | 01.01.1900 | 07.02.2001 | (null) | (null) | (null) | (null) | (null) | (null) | (null) | (null) |