FOR XML PATH in Dynamic Pivot Table

FOR XML PATH in Dynamic Pivot Table

The most useful functionality of this clause is to concatenate multiple columns into a single row. You may wonder when exactly do you need to use this in practice? I'll tell you in a bit. Have you ever used Pivot in your static queries? If yes, then in that situation you had to know beforehand what values you needed to use after IN clause. To clarify take a look at this static pivot query:

SELECT * FROM
(
SELECT YEAR(OrderDate) as OrderYear,
????????Category,
TotalOrder
 FROM OrderTAble 
) AS D
PIVOT (SUM(TotalOrder)
FOR OrderYear IN ([2020],[2021],[2022]))
as P         
No alt text provided for this image
Output of static pivot table


In the query above we explicitly mentioned years(2020,2021,2022) to have those as columns of the output.

So what if two months later we want to have year 2023 order records as well? In that case do you really want to come back and add 2023 hard-coded in your query?

So let's go back to our main topic. You asked when do you need to use FOR XML PATH in practice? Here is your answer: To write Dynamic Pivot technique. One of the most efficient yet simplest ways to write Dynamic Pivot is to use FOR XML PATH clause.

For practice purposes I created a test table called OrderTable and I want to pivot this table to have Order Years as columns. It is exactly like the example above but instead of using static Pivot, we are going to use dynamic pivot. Here is the query for create a dynamic pivot table:


use tempdb;
drop table? if exists OrderTable;
create table OrderTable
(
? ? OrderDate datetime,
? ? Category Varchar(40),
? ? TotalOrder Int
)

insert into OrderTable values ('2022/01/12', 'A', 300)
insert into OrderTable values ('2020/01/21', 'B', 800)
insert into OrderTable values ('2021/01/21', 'C', 600)
insert into OrderTable values ('2023/01/21', 'D', 300)
insert into OrderTable values ('2023/01/21', 'E', 400)

DECLARE @cols AS NVARCHAR(MAX),
? ? @query? AS NVARCHAR(MAX);


SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(Year(OrderDate))?
? ? ? ? ? ? FROM OrderTable c
? ? ? ? ? ? FOR XML PATH(''), TYPE
? ? ? ? ? ? ).value('.', 'NVARCHAR(MAX)')?
? ? ? ? ,1,1,'')

select @cols as 'Columns'


set @query = 'SELECT Category, ' + @cols + ' from?
? ? ? ? ? ? (
? ? ? ? ? ? ? ? select Year(OrderDate) as YearOrder
? ? ? ? ? ? ? ? ? ? , TotalOrder
? ? ? ? ? ? ? ? ? ? , category
? ? ? ? ? ? ? ? from OrderTable
? ? ? ? ? ?) x
? ? ? ? ? ? pivot?
? ? ? ? ? ? (
? ? ? ? ? ? ? ? ?sum(TotalOrder)
? ? ? ? ? ? ? ? for YearOrder in (' + @cols + ')
? ? ? ? ? ? ) p '

execute(@query)

drop table OrderTable        

The output is shown below:

No alt text provided for this image
Output of using FOR XML PATH and Dynamic Pivot

In this example as query shows we used various functions like STUFF and QUOTENAME alongside FOR XML PATH to achieve the first result (Columns). With the use of FOR XML PATH we were able to concatenate all years into a single row so that we could feed it properly to the IN clause of Pivot. Now if years go by we do not need to worry about adding them to our pivot query.

Thank you for reading. I hope this article was helpful for you.

要查看或添加评论,请登录

Sky Yaghoobi的更多文章

  • Best Practices For Sql Server Indexes

    Best Practices For Sql Server Indexes

    Most Sql Server professionals allege that creating indexes is a double-edged sword. In other words, if only we use best…

  • What is Transaction Log Backup in Sql Server?

    What is Transaction Log Backup in Sql Server?

    The first thing you need to know is that when your database recovery model is either Full or Bulked Logged, you can…

  • What are Trace Flags 1117 and 1118 In Sql Server?

    What are Trace Flags 1117 and 1118 In Sql Server?

    Trace Flag 1117 First of all, what is a trace flag? A trace flag is an advanced property with which you can set and…

    1 条评论