动态 PIVOT
PIVOT
查询的一个问题是,如果要将它们视为列,则必须指定 IN
选择内的所有值。解决此问题的一种快速方法是创建动态 IN 选择,使你的 PIVOT
动态化。
为了演示,我们将在 Bookstore
的数据库中使用表 Books
。我们假设该表已经完全去标准化并且具有以下列
Table: BooksBookId (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
现在,如果我们需要查询数据库并找出每年购买到书店的英语,俄语,德语,印地语,拉丁语的书籍数量,并以小报告格式显示我们的输出,我们可以使用像这样的 PIVOT 查询
SELECT * FROM
(
SELECT YearBoughtIntoStore AS [Year Bought],[Language], NumberOfBooks
FROM BookList
) sourceData
PIVOT
(
SUM(NumberOfBooks)
FOR [Language] IN (English, Russian, German, Hindi, Latin)
) pivotrReport
特殊情况是当我们没有完整的语言列表时,我们将使用如下的动态 SQL
DECLARE @query VARCHAR(4000)
DECLARE @languages VARCHAR(2000)
SELECT @languages =
STUFF((SELECT DISTINCT '],['+LTRIM([Language])FROM [dbo].[BookList]
ORDER BY '],['+LTRIM([Language]) FOR XML PATH('') ),1,2,'') + ']'
SET @query=
'SELECT * FROM
(SELECT YearBoughtIntoStore AS [Year Bought],[Language],NumberOfBooks
FROM BookList) sourceData
PIVOT(SUM(NumberOfBooks)FOR [Language] IN ('+ @languages +')) pivotrReport' EXECUTE(@query)