TSQL PIVOT MULTIPLE COLUMNS
Since you want to pivot multiple columns of data, I would first suggest unpivoting the result
, score
and grade
columns so you don't have multiple columns but you will have multiple rows.
Depending on your version of SQL Server you can use the UNPIVOT function or CROSS APPLY. The syntax to unpivot the data will be similar to:
select ratio, col, value
from GRAND_TOTALS
cross apply
(
select 'result', cast(result as varchar(10)) union all
select 'score', cast(score as varchar(10)) union all
select 'grade', grade
) c(col, value)
See SQL Fiddle with Demo. Once the data has been unpivoted, then you can apply the PIVOT function:
select ratio = col,
[current ratio], [gearing ratio], [performance ratio], total
from
(
select ratio, col, value
from GRAND_TOTALS
cross apply
(
select 'result', cast(result as varchar(10)) union all
select 'score', cast(score as varchar(10)) union all
select 'grade', grade
) c(col, value)
) d
pivot
(
max(value)
for ratio in ([current ratio], [gearing ratio], [performance ratio], total)
) piv;
See SQL Fiddle with Demo. This will give you the result:
| RATIO | CURRENT RATIO | GEARING RATIO | PERFORMANCE RATIO | TOTAL |
|--------|---------------|---------------|-------------------|-----------|
| grade | Good | Good | Satisfactory | Good |
| result | 1.29400 | 0.33840 | 0.04270 | (null) |
| score | 60.00000 | 70.00000 | 50.00000 | 180.00000 |
How to PIVOT multiple columns using SQL Server
You just need to pivot twice and combine the results, e.g.:
-- Setup example data...
drop table if exists #Example;
create table #Example (
VendorId int,
Category varchar(10),
FirstSaleDate date,
StoreId int
);
insert #Example (VendorId, [Category], FirstSaleDate, StoreId)
values
(1, 'Car', '2021-01-01', 12),
(1, 'Clothes', '2021-01-02', 13),
(1, 'Toys', '2021-01-03', 14),
(1, 'Food', '2021-01-04', 15),
(1, 'Others', '2021-01-05', 15);
-- Pivot data...
with FirstSales as (
select VendorId, Category, FirstSaleDate from #Example
), Stores as (
select VendorId, 'StoreId_' + Category as Category, StoreId from #Example
)
select
FirstSales.VendorId,
Car, StoreId_Car,
Clothes, StoreId_Clothes,
Toys, StoreId_Toys,
Food, StoreId_Food,
Others, StoreId_Others
from (
select VendorId, Car, Clothes, Toys, Food, Others
from FirstSales
pivot (min(FirstSaleDate) for Category in ([Car], [Clothes], [Toys], [Food], [Others])) as pvt
) as FirstSales
join (
select VendorId, StoreId_Car, StoreId_Clothes, StoreId_Toys, StoreId_Food, StoreId_Others
from Stores
pivot (min(StoreId) for Category in ([StoreId_Car], [StoreId_Clothes], [StoreId_Toys], [StoreId_Food], [StoreId_Others])) as pvt
) as Stores on Stores.VendorId=FirstSales.VendorId;
Pivot on multiple columns (T-SQL)
First you need to unpivot
the data then you can pivot
the result
Sample data
create table piv(TimeRange varchar(50),Type varchar(50), Month int,ActionDuration int, GrossValue bigint, NetValue bigint)
insert piv values
('09:00-10:00','Bonus' ,1 ,30 ,0 ,0 ),
('09:00-10:00','Bonus' ,1 ,30 ,0 ,0 ),
('09:00-10:00','Billed' ,1 ,30 ,77982 ,701838 ),
('09:00-10:00','Not Billed' ,1 ,30 ,506124 ,4555116 ),
('10:00-11:00','Bonus' ,1 ,30 ,0 ,0 ),
('10:00-11:00','Billed' ,1 ,30 ,109739 ,987651 ),
('10:00-11:00','Billed' ,1 ,30 ,109739 ,987651 ),
('10:00-11:00','Not Billed' ,1 ,30 ,98021 ,882189 ),
('09:00-10:00','Bonus' ,2 ,30 ,0 ,0 ),
('09:00-10:00','Billed' ,2 ,30 ,288947 ,2600523 ),
('09:00-10:00','Billed' ,2 ,30 ,288947 ,2600523 ),
('09:00-10:00','Not Billed' ,2 ,30 ,64669 ,582021 ),
('10:00-11:00','Bonus' ,2 ,30 ,0 ,0 ),
('10:00-11:00','Billed' ,2 ,30 ,48738 ,438642 ),
('10:00-11:00','Not Billed' ,2 ,30 ,269969 ,2429721 )
Query
SELECT *
FROM (SELECT TimeRange,
TYPE,
DATA,
left(DateName( month , DateAdd( month , month , 0 ) - 1 ),3) + ' '
+ COLUMN_NAME AS PIV_COL
FROM Yourtable
CROSS APPLY (VALUES ('ActionDuration',ActionDuration),
('GrossValue',GrossValue),
('NetValue',NetValue)) CS(COLUMN_NAME, DATA)) a
PIVOT (sum(DATA)
FOR PIV_COL IN([Jan ActionDuration],
[Jan GrossValue],
[Jan NetValue],
[Feb ActionDuration],
[Feb GrossValue],
[Feb NetValue])) PV
Result
TimeRange TYPE Jan ActionDuration Jan GrossValue Jan NetValue Feb ActionDuration Feb GrossValue Feb NetValue
----------- ----------- ------------------ -------------- ------------ ------------------ -------------- -------------
09:00-10:00 Billed 30 77982 701838 60 577894 5201046
10:00-11:00 Billed 60 219478 1975302 30 48738 438642
09:00-10:00 Bonus 60 0 0 30 0 0
10:00-11:00 Bonus 30 0 0 30 0 0
09:00-10:00 Not Billed 30 506124 4555116 30 64669 582021
10:00-11:00 Not Billed 30 98021 882189 30 269969 2429721
Pivoting on multiple columns with multiple sums
We can try handling this by taking a union approach:
WITH cte AS (
SELECT [Type], Total1 AS Total, Account1 AS Account FROM #temp
UNION ALL
SELECT [Type], Total2, Account2 FROM #Temp
)
SELECT
[Type],
SUM(CASE WHEN Account = '1220' THEN Total ELSE 0 END) AS [1220],
SUM(CASE WHEN Account = '4110' THEN Total ELSE 0 END) AS [4110]
FROM cte
GROUP BY
Type;
Demo
The basic strategy here is to bring all accounts and totals into two separate columns, and then aggregate/pivot just over those single columns. This gets around the problem of having the data you want to aggregate across multiple columns. The best long term fix might be to change your data structure to just have a single column for the account and total.
SQL Server 2008, Pivot based on multiple columns
I don't think you can easily pivot on multiple columns using built-in functionality, but you can use the ROW_NUMBER()
window function together with conditional aggregation to achieve the desired effect.
Something like:
WITH CTE_Data AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY Model, Size ORDER BY SKU) AS RowNumber
FROM #Data
)
SELECT
CD.Model, CD.Size
, SKU = MAX(CASE WHEN CD.RowNumber = 1 THEN CD.SKU END)
, Color = MAX(CASE WHEN CD.RowNumber = 1 THEN CD.Color END)
, AltSKU1 = MAX(CASE WHEN CD.RowNumber = 2 THEN CD.SKU END)
, AltColor1 = MAX(CASE WHEN CD.RowNumber = 2 THEN CD.Color END)
, AltSKU2 = MAX(CASE WHEN CD.RowNumber = 3 THEN CD.SKU END)
, AltColor2 = MAX(CASE WHEN CD.RowNumber = 3 THEN CD.Color END)
FROM CTE_Data CD
GROUP BY Model, Size
ORDER BY Model, Size
Yielding the following result:
Model | Size | SKU | Color | AltSKU1 | AltColor1 | AltSKU2 | AltColor2 |
---|---|---|---|---|---|---|---|
MAC | Large | 9 | Silver | null | null | null | null |
MAC | Normal | 3 | Silver | 5 | Blue | null | null |
PC | Large | 7 | Blue | 8 | Red | null | null |
PC | Normal | 1 | Blue | 2 | Red | 4 | Green |
Phone | Normal | 6 | Blue | null | null | null | null |
SQL Pivot multiple columns without forcing aggregate
The problem was that I needed a row_number per every group of column names. So the below worked
SELECT DISTINCT TrnYear,
TrnMonth,
EntryDate,
TrnTime,
StockCode,
Warehouse
FROM
(SELECT (ROW_NUMBER() OVER (ORDER BY dw_view_change_event_nr) - 1) / 6 + 1 AS rn,
COLUMN_NAME ,
column_value
FROM
#TheTable AS tmp) AS src PIVOT (MAX(column_value)
FOR COLUMN_NAME in ([TrnYear], [TrnMonth], [EntryDate], [TrnTime], [StockCode], [Warehouse])) AS piv
Pivot/transpose rows into columns efficiently with multiple columns
SELECT
[Num1],
[Type1],
[Code],
[Group],
[DA],
[123],
[234]
FROM
yourTable
PIVOT
(
MAX([value])
FOR [account] IN ([123], [234])
)
AS PivotTable
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=7fbe16b9254aa5ee60a23e43eec9597f
Pivot on Dependent Multiple Columns
You can use a CROSS APPLY
to unpivot/expand the rows, and then pivot the results.
Example
Select *
From (
Select A.Super_Location
,B.*
From TestTable A
Cross Apply ( values ( concat(location,'_Min_',year),[Min] )
,( concat(location,'_Division_',year),[Value] )
) B(Item,Value)
) src
Pivot (max(Value) for Item in ( [Primary_Min_2020 ],[Primary_Min_2019],[Secondary_Min_2020], [Secondary_Min_2019],[Primary_Division_2020],[Secondary_Division_2020], [Secondary_Division_2019] ) ) pvt
Results
NOTE: If it helps with the visualization, the subquery generates the following:
SQL server Pivot on Multiple Columns
I would unpivot the columns into pairs first, then pivot them. Basically the unpivot process will convert the pairs of columns (rscd
, position
and accd
, aposition
) into rows, then you can apply the pivot. The code will be:
select id, [1], [2], [11], [12]
from
(
select id, col, value
from #t
cross apply
(
select rscd, position union all
select Accd, position + 10
) c (value, col)
) d
pivot
(
max(value)
for col in ([1], [2], [11], [12])
) piv;
See SQL Fiddle with Demo
Related Topics
Pagination with The Stored Procedure
Sql Query to Sum Fields from Different Tables
How to Use SQL Server Stored Procedures in Microsoft Powerbi
Sql: How to Order Null and Empty Entries to The Front in an Orderby
SQL Server Management Studio 2012 Hangs
How to Check for The SQL Server Version Using Powershell
Iterate Through a List of Strings in SQL Server
How to Use Max() on a Subquery Result
Efficient Time Series Querying in Postgres
How to Get Current Database and User Name with 'select' in Postgresql
Update Statement with Multiple Where Conditions
Sql Collation Conflict When Comparing to a Column in a Temp Table
How to Emulate Lpad/Rpad with SQLite
Sql Server 2012 Random String from a List
Merge Multiple Rows with Same Id into One Row