USING SQL PIVOT
This is perhaps one of the best things that I’ve come across
in MS SQL while working on OGC. When you need to quickly convert something from
rows to column or column to rows, this is the numero uno solution. Without ado,
let me quickly introduce you to the syntax and most common use of a SQL PIVOT
keyword.
SYNTAX
The syntax for PIVOT in most simplest expression format as
SELECT *
FROM [SOURCEDATA] PIVOT( SUM([ColumnToBePivotedOn]) FOR [ColumnWhoseRowsWillBeMadeIntoColumns] IN (NewColumn1,
NewColumn2, NewColumn3, NewColumn4,…)) AS PivotTableName
NOTES
- We can use any aggregate function in lieu of
SUM() like MAX(), MIN() etc.
- [SourceData] can be replaced with a complex
source like a JOIN between two table or an inner select query
- If we need to add more columns to the PIVOT
result it can be done provided these are not to be pivoted and will be used for
aggregation of pivot data i.e. drilling down further.
EXAMPLE
Imagine a table Books in a Bookstore’s database. For
simplicity we assume that the table is quite denormalised and has following
columns
- BookId (Primary Key Column)
- Name
- Language
- NumberOfPages
- EditionNumber
- YearOfPrint
- YearBoughtIntoStore
- ISBN
- AuthorName
- Price
NumberOfUnitsSold
CREATE TABLE
[dbo].[BookList](
[BookId] [int] NOT NULL,
[Name] [nvarchar](100) NULL,
[Language] [nvarchar](100) NULL,
[NumberOfPages] [int]
NULL,
[EditionNumber] [nvarchar](10) NULL,
[YearOfPrint] [int] NULL,
[YearBoughtIntoStore] [int]
NULL,
[NumberOfBooks] [int]
NULL,
[ISBN] [nvarchar](30) NULL,
[AuthorName] [nvarchar](200) NULL,
[Price] [money] NULL,
[NumberOfUnitsSold] [int]
NULL,
CONSTRAINT [PK_BookList]
PRIMARY KEY CLUSTERED
(
[BookId] ASC
)WITH (PAD_INDEX =
OFF, STATISTICS_NORECOMPUTE =
OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Now if we need to query on the database and figure out
number of books in English, Russian, German, Hindi, Latin languages bought into
the bookstore every year and present our output in a small report format, we
can use PIVOT query like this
SELECT * FROM
(SELECT YearBoughtIntoStore AS [Year Bought],[Language], NumberOfBooks
FROM BookList) sourceData PIVOT(SUM(NumberOfBooks)
FOR [Language] IN (English, Russian, German, Hindi, Latin)) pivotrReport
This will give a report like
Year Bought
|
English
|
Russian
|
German
|
Hindi
|
Latin
|
2009
|
24
|
NULL
|
50
|
23
|
NULL
|
2010
|
12
|
13
|
NULL
|
NULL
|
12
|
2011
|
30
|
NULL
|
NULL
|
44
|
NULL
|
2012
|
NULL
|
NULL
|
28
|
NULL
|
NULL
|
2013
|
45
|
NULL
|
10
|
NULL
|
NULL
|
We’ll see some more details on this in later blogs. Hope
this was helpful.