THE SOURCE TABLE Looks like this:
h1_ind = 1 indicates a row that contains column names.
Source
col1 col2 col3 col4 h1_ind table_sheet y w
Route CNG/Diesel Freq Weekly Miles 1 Summary 2021 Week 1
a 5 B 6 2 Summary 2021 Week 1
b 1 1 1 3 Summary 2021 Week 1
c 5 B 6 4 Summary 2021 Week 1
d 1 1 1 5 Summary 2021 Week 1
Route CNG/Diesel Freq Weekly Miles 1 Summary 2021 Week 2
a 5 B 6 2 Summary 2021 Week 2
b 1 1 1 3 Summary 2021 Week 2
c 5 B 6 4 Summary 2021 Week 2
d 1 1 1 5 Summary 2021 Week 2
Then I convert to this: (FOR WEEK 1 ONLY)
Data
IN column table_sheet y w value h1_ind
col1 Route Summary 2021 Week 1 a 2
col2 CNG/Diesel Summary 2021 Week 1 5 3
col3 Freq Summary 2021 Week 1 B 4
col4 Weekly Miles Summary 2021 Week 1 6 5
col1 Route Summary 2021 Week 1 b 2
col2 CNG Summary 2021 Week 1 1 3
col3 Freq Summary 2021 Week 1 1 4
col4 Weekly Miles Summary 2021 Week 1 1 5
col1 Route Summary 2021 Week 1 c 2
col2 CNG/Diesel Summary 2021 Week 1 5 3
col3 Freq Summary 2021 Week 1 B 4
col4 Weekly Miles Summary 2021 Week 1 6 5
col1 Route Summary 2021 Week 1 d 2
col2 CNG Summary 2021 Week 1 1 3
col3 Freq Summary 2021 Week 1 1 4
col4 Weekly Miles Summary 2021 Week 1 1 5
I would like to be able to present as desired below.
(FOR WEEK 1 ONLY)
Desired output:
table_sheet y w Route CNG/Diesel Freq Weekly Miles
Summary 2021 Week 1 a 5 B 6
Summary 2021 Week 1 b 1 1 1
Summary 2021 Week 1 c 5 B 6
Summary 2021 Week 1 d 1 1 1
how can I do this? Pivot only gives me one row (MAX, MIN) I need all rows to presented.
You can use a PIVOT
, the key is to make sure h1_ind
is also part of the grouping and not being aggregated.
CROSS APPLY
PIVOT
.WITH Headers AS (
SELECT *,
Col1Header = MAX(CASE WHEN h1_ind = '1' THEN col1 END) OVER (PARTITION BY table_sheet, y, w),
Col2Header = MAX(CASE WHEN h1_ind = '1' THEN col2 END) OVER (PARTITION BY table_sheet, y, w),
Col3Header = MAX(CASE WHEN h1_ind = '1' THEN col3 END) OVER (PARTITION BY table_sheet, y, w),
Col4Header = MAX(CASE WHEN h1_ind = '1' THEN col4 END) OVER (PARTITION BY table_sheet, y, w)
FROM YourTable t
),
Unpivoted AS (
SELECT
t.table_sheet,
t.y,
t.w,
t.h1_ind,
v.Header,
v.Value
FROM Headers t
CROSS APPLY (VALUES
(Col1Header, Col1),
(Col2Header, Col2),
(Col3Header, Col3),
(Col4Header, Col4)
) v(Header, Value)
WHERE h1_ind > 1
)
SELECT *
FROM Unpivoted
PIVOT (
MAX(Value) FOR Header IN
(Route, [CNG/Diesel], Freq, [Weekly Miles])
) pvt;
You could also use MAX(CASE
conditional aggregate here if you want, instead of PIVOT
.
WITH ...
SELECT
t.table_sheet,
t.y,
t.w,
Route = MAX(CASE WHEN v.Header = 'Route' THEN v.Value END),
[CNG/Diesel] = MAX(CASE WHEN v.Header = 'CNG/Diesel' THEN v.Value END),
Freq = MAX(CASE WHEN v.Header = 'Freq' THEN v.Value END),
[Weekly Miles] = MAX(CASE WHEN v.Header = 'Weekly Miles' THEN v.Value END)
FROM Unpivoted
GROUP BY
t.table_sheet,
t.y,
t.w
t.h1_ind;