I have the below results within a table.
x
MonthYear MonthNumber YearDate Clients NonClients
-------------------------------------------------
Feb-20 2 2020 46 0
Jan-20 1 2020 21 0
Mar-20 3 2020 37 0
The SQL
CREATE TABLE [dbo].[Results](
[MonthYear] [nvarchar](35) NULL,
[MOnthNumber] [int] NULL,
[YearDate] [int] NULL,
[Clients] [int] NULL,
[NonClients] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Results] ([MonthYear], [MOnthNumber], [YearDate], [Clients], [NonClients]) VALUES (N'February 2020', 2, 2020, 46, 0)
GO
INSERT [dbo].[Results] ([MonthYear], [MOnthNumber], [YearDate], [Clients], [NonClients]) VALUES (N'January 2020', 1, 2020, 21, 2)
GO
INSERT [dbo].[Results] ([MonthYear], [MOnthNumber], [YearDate], [Clients], [NonClients]) VALUES (N'March 2020', 3, 2020, 37, 0)
GO
How can I turn this into the following with it in date order, and the MonthYear being flexible where it could contain any number of months/years?
Jan-20 Feb-20 Mar-20
------------------------------------------
Non Clients 2 0 0
Clients 21 46 37
I’ve got the following so far, but can’t manage to finish it off:
DECLARE
@columns NVARCHAR(MAX) = '',
@sql NVARCHAR(MAX) = ''
-- select the column headers
SELECT
@columns+=QUOTENAME(MonthYear) + ','
FROM
Results R
order by
YearDate desc,
MonthNumber desc
-- construct dynamic SQL
SET @sql ='
SELECT * FROM
(
select * from #Results
) t
PIVOT(
Sum(Clients)
FOR MonthYear IN ('+ @columns +')
) AS pivot_table
'
-- execute the dynamic SQL
EXECUTE sp_executesql @sql
Advertisement
Answer
You would need both Unpiovt
and Pivot
to achieve the desired result. I’ve added to your code.
--unpivoting
drop table if exists #results
select MonthYear, MOnthNumber, YearDate, col, val, dense_rank() over (order by YearDate desc, MonthNumber) rn --to preserve the order
into #results
from
(
select MonthYear, MOnthNumber, YearDate, Clients, NonClients
from Results
)t
unpivot
(
val for col in (Clients,NonClients)
)upvt
DECLARE
@columns NVARCHAR(MAX),
@sql NVARCHAR(MAX) = ''
-- select the column headers
SELECT
@columns = COALESCE(@columns + ', ', '') + QUOTENAME(MonthYear)
FROM
(select distinct MonthYear, rn from #results)R
order by rn
-- construct dynamic SQL
SET @sql ='
SELECT col as C_or_NC, '+@columns+' FROM
(
select MonthYear, col, val from #Results
) t
PIVOT(
Sum(val)
FOR MonthYear IN ('+ @columns +')
) AS pivot_table
order by 1 desc'
print @sql
-- execute the dynamic SQL
EXECUTE sp_executesql @sql
please see the demo here.