USE Northwind GO
IF EXISTS(SELECT name FROM sysobjects WHERE name = N'pivot' AND type = 'U') DROP TABLE pivot GO
-- 用 T-SQL 的 DDL 语句创建一个演示用的表 CREATE TABLE Pivot ( Year SMALLINT, Quarter TINYINT, Amount DECIMAL(2,1) ) GO
-- 对这个演示用的表插入数据 INSERT INTO Pivot VALUES (1990, 1, 1.1) INSERT INTO Pivot VALUES (1990, 2, 1.2) INSERT INTO Pivot VALUES (1990, 3, 1.3) INSERT INTO Pivot VALUES (1990, 4, 1.4) INSERT INTO Pivot VALUES (1991, 1, 2.1) INSERT INTO Pivot VALUES (1991, 2, 2.2) INSERT INTO Pivot VALUES (1991, 3, 2.3) INSERT INTO Pivot VALUES (1991, 4, 2.4) -- 下面这行在 SQL SERVER 的联机丛书中是没有的,为了验证我们自己写的交叉表查询,需要增加一列 -- 其中的 5 可是随便写的,实际中可不会存在哦 INSERT INTO Pivot VALUES (1991, 5, 2.4)
GO
--下面是用于创建旋转结果的 SELECT 语句:
SELECT Year, SUM(CASE Quarter WHEN 1 THEN Amount ELSE 0 END) AS Q1, SUM(CASE Quarter WHEN 2 THEN Amount ELSE 0 END) AS Q2, SUM(CASE Quarter WHEN 3 THEN Amount ELSE 0 END) AS Q3, SUM(CASE Quarter WHEN 4 THEN Amount ELSE 0 END) AS Q4 FROM Northwind.dbo.Pivot GROUP BY Year GO
-- 上面部分都是照抄联机丛书的 -- 下面开始可就是我们自己写的咯
declare @a TINYINT declare @nSQL nvarchar(4000) -- 注意,以下这句是必须的,否则 @nSQL 就是 NULL ,NULL 与字符串相加都是 NULL set @nSQL =''
-- 下面开始就是用游标读取 pivot 表中的 quarter 这列有多少不重复数值了,一个数值将生成一列 -- 有关游标的使用基本是从联机丛书《FETCH Transact-SQL 参考》这个章节COPY 过来的 -- 不同的是增加了 into @a 这句,这句的目的是将游标所指的这一行的某一列(quarter)的数值存入变量 DECLARE Quarter_cursor CURSOR FOR SELECT Distinct [Quarter] FROM Northwind.dbo.pivot
OPEN Quarter_cursor
FETCH NEXT FROM Quarter_cursor into @a WHILE @@FETCH_STATUS = 0 BEGIN -- 只要以文字方式组织联机丛书中的 -- 'SUM(CASE Quarter WHEN 1 THEN Amount ELSE 0 END) AS Q1' -- 这行代码即可。 set @nSQL=@nSQL + ',sum(case quarter when ' + cast(@a as nvarchar(5)) + ' then amount else 0 end) as q' + cast(@a as nvarchar(5)) + ' ' FETCH NEXT FROM Quarter_cursor into @a END
CLOSE Quarter_cursor DEALLOCATE Quarter_cursor
-- 最后是仍旧按照联机丛书的 SELECT 语句的格式把 SQL 语句组织起来 set @nSQL='select year' + @nSQL + 'FROM Northwind.dbo.Pivot GROUP BY Year' -- 打印出完整的语句看看: print @nsql
-- 将结果集输出即可 execute sp_executesql @nsql go |