sql语句实现行转列查询

面试时遇到一个这样的sql题如下:

表sales
[table]
|年份 | 季度 | 金额|
|1991 | 1 | 11|
|1991 | 2 | 22|
|1991 | 3 | 33|
|1991 | 4 | 44|
|1992 | 1 | 55|
|1992 | 2 | 66|
|1992 | 3 | 77|
|1992 | 4 | 88|
[/table]
查询结果如下:
[table]
|年份 | 第一季度 | 第二季度 | 第三季度 |第四季度|
|1991 | 11 | 22 | 33 | 44|
|1992 | 55 | 66 | 77 | 88|

[/table]

请写出sql语句。

当我看到这样的问题时我的内心是崩溃的,一点思路都没有!回到家赶紧查上网查了一下,记录备忘。

建表:


CREATE TABLE [dbo].[sales](
[id] [int] IDENTITY(1,1) NOT NULL,
[year] [int] NULL,
[jidu] [int] NULL,
[jine] [int] NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


有两种方法:

一、使用case when 实现:

 
SELECT
year as '年份',
max(CASE jidu WHEN 1 THEN jine END) AS '第一季度',
max(CASE jidu WHEN 2 THEN jine END) AS '第二季度',
max(CASE jidu WHEN 3 THEN jine END) AS '第三季度',
max(CASE jidu WHEN 4 THEN jine END) AS '第四季度'
FROM sales group by year


很容易理解,但写起来很麻烦。下面介绍下一种。

二、使用pivot函数:

使用pivot函数时须注意[color=red]对升级到 SQL Server 2005 或更高版本的数据库使用 PIVOT 和 UNPIVOT 时,必须将数据库的兼容级别设置为 90 或更高[/color]。
参考:
[url]https://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx[/url]
PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。

PIVOT的语法:
SELECT <非透视的列>,
[第一个透视的列] AS <列名称>,
[第二个透视的列] AS <列名称>,
...
[最后一个透视的列] AS <列名称>,
FROM
(<生成数据的 SELECT 查询>)
AS <源查询的别名>
PIVOT
(
<聚合函数>(<要聚合的列>)
FOR
[<包含要成为列标题的值的列>]
IN ( [第一个透视的列], [第二个透视的列],
... [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;

按照上述语法写出sql:


select year as 年份,[1] as 第一季度,[2] as 第二季度,[3] as 第三季度,[4] as 第四季度 from sales pivot (SUM(jine) FOR jidu IN ([1],[2],[3],[4]))a


看着就清秀,执行结果如下:

[img]http://dl2.iteye.com/upload/attachment/0127/9054/215f34fb-775f-30b6-8ef4-1cfdf905b709.jpg[/img]

这是什么鬼……

其实很明显,分组出现了问题,但是按照语法[color=red]只能指定需要横向显示的列即聚合函数中的列和要成为列标题的值的列,不能明确定义分组列[/color]。用作分组的列是PIVOT函数中没有应用到的列(即 字段 id),会根据id和year两个字段分组。

注意源查询中是可以使用select语句的,PIVOT可以操作结果集,因此只需要将源查询中不显示id这个字段就可以了:


select year as 年份,[1] as 第一季度,[2] as 第二季度,[3] as 第三季度,[4] as 第四季度 from (select year,jidu,jine from sales) as t1 pivot (SUM(jine) FOR jidu IN ([1],[2],[3],[4])) as a --'t1'和'a'这两个别名必须得有要不会报错。


执行结果:
[img]http://dl2.iteye.com/upload/attachment/0127/9060/a59c05c7-d6ff-383e-b75c-925a0c355bea.jpg[/img]

终于对了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值