SQL基础教程之行转列Pivot函数

前言

未来的一个月时间中,会总结一系列SQL知识点,一次只总结一个知识点,尽量说明白,下面来说说SQL 中常用Pivot 函数(这里是用的数据库是SQLSERVER,与其他数据库是类似的,大家放心看就好)

让我们先从一个虚构的场景中来着手吧

万国来朝,很多供应商每天都汇报各自的收入情况。先来创建一个DailyIncome 表

create table DailyIncome(VendorId nvarchar(10), IncomeDay nvarchar(10), IncomeAmount int)

--VendorId 供应商ID,
--IncomeDay 收入时间
--IncomeAmount 收入金额

紧接着来插入数据看看

(留意看下,有的供应商某天中会有多次收入,应该是分批进账的)

insert into DailyIncome values ('SPIKE', 'FRI', 100)
insert into DailyIncome values ('SPIKE', 'MON', 300)
insert into DailyIncome values ('FREDS', 'SUN', 400)
insert into DailyIncome values ('SPIKE', 'WED', 500)
insert into DailyIncome values ('SPIKE', 'TUE', 200)
insert into DailyIncome values ('JOHNS', 'WED', 900)
insert into DailyIncome values ('SPIKE', 'FRI', 100)
insert into DailyIncome values ('JOHNS', 'MON', 300)
insert into DailyIncome values ('SPIKE', 'SUN', 400)
insert into DailyIncome values ('JOHNS', 'FRI', 300)
insert into DailyIncome values ('FREDS', 'TUE', 500)
insert into DailyIncome values ('FREDS', 'TUE', 200)
insert into DailyIncome values ('SPIKE', 'MON', 900)
insert into DailyIncome values ('FREDS', 'FRI', 900)
insert into DailyIncome values ('FREDS', 'MON', 500)
insert into DailyIncome values ('JOHNS', 'SUN', 600)
insert into DailyIncome values ('SPIKE', 'FRI', 300)
insert into DailyIncome values ('SPIKE', 'WED', 500)
insert into DailyIncome values ('SPIKE', 'FRI', 300)
insert into DailyIncome values ('JOHNS', 'THU', 800)
insert into DailyIncome values ('JOHNS', 'SAT', 800)
insert into DailyIncome values ('SPIKE', 'TUE', 100)
insert into DailyIncome values ('SPIKE', 'THU', 300)
insert into DailyIncome values ('FREDS', 'WED', 500)
insert into DailyIncome values ('SPIKE', 'SAT', 100)
insert into DailyIncome values ('FREDS', 'SAT', 500)
insert into DailyIncome values ('FREDS', 'THU', 800)
insert into DailyIncome values ('JOHNS', 'TUE', 600)

让我们先来看看前十行数据:

select top 10 * from DailyIncome

如图所示:


DailyIncome

虽然数据是能够完全给展示了,但好像一眼望去不能得到对我们用处更大的信息,比如说我们想得到每个供应商的每天的总收入,这时我们应该做一些数据形式的转变了,平常的所用的是这样的。

select VendorId ,
sum(case when IncomeDay='MoN' then IncomeAmount else 0 end) MON,
sum(case when IncomeDay='TUE' then IncomeAmount else 0 end) TUE,
sum(case when IncomeDay='WED' then IncomeAmount else 0 end) WED,
sum(case when IncomeDay='THU' then IncomeAmount else 0 end) THU,
sum(case when IncomeDay='FRI' then IncomeAmount else 0 end) FRI,
sum(case when IncomeDay='SAT' then IncomeAmount else 0 end) SAT,
sum(case when IncomeDay='SUN' then IncomeAmount else 0 end) SUN
from DailyIncome group by VendorId

得到如下的结果:


case when结果

如果大家仔细看结果的话,会有这样的发现,这是把VendorID进行了分组,并且对于每组中IncomeDay这一列中的值都变成了新的列名字,然后对IncomeAmount进行求和操作。

这样写可能是有些麻烦,别着急,我们用Pivot函数进行行转列试下。

select * from DailyIncome ----第一步
pivot
(
sum (IncomeAmount) ----第三步
for IncomeDay in ([MON],[TUE],[WED],[THU],[FRI],[SAT],[SUN]) ---第二步
) as AvgIncomePerDay

来解释下,要想用好Pivot函数,应该理解代码注释中的这几步。

第一步:肯定是要明白数据源了,这里是DailyIncome

第二步:要明白要想让哪一列的值做新的列名字

第三步:要明白对于这新的列要求那些值呢?

下面有个练习题目,做之前不要看答案啊

问:对于SPIKE这家供应商来说,每天最大的入账金额。

select * from DailyIncome
pivot (max (IncomeAmount) for IncomeDay in ([MON],[TUE],[WED],[THU],[FRI],[SAT],[SUN])) as MaxIncomePerDay
where VendorId in ('SPIKE')

参考链接如下:

1.Pivot tables in SQL Server. A simple sample

2.行转列:SQL SERVER PIVOT与用法解释

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • SQL行转列和列转行代码详解

    行列互转,是一个经常遇到的需求.实现的方法,有case when方式和2005之后的内置pivot和unpivot方法来实现. 在读了技术内幕那一节后,虽说这些解决方案早就用过了,却没有系统性的认识和总结过.为了加深认识,再总结一次. 行列互转,可以分为静态互转,即事先就知道要处理多少行(列);动态互转,事先不知道处理多少行(列). --创建测试环境 USE tempdb; GO IF OBJECT_ID('dbo.Orders') IS NOT NULL DROP TABLE dbo.Orde

  • table 行转列的sql详解

    一.要求 1 创建数据表 CREATE TABLE [dbo].[StuScore]( [stuid] [int] NOT NULL, [subject] [nvarchar](30) NULL, [score] [decimal](5, 1) NULL ) 2 插入测试数据 stuid subject score 3 chinese 76.0 3 math 73.0 4 chinese 82.0 5 chinese 66.0 5 math 93.0 6 chinese 67.0 7 math

  • Sql Server 2000 行转列的实现(横排)

    我们用到的表结构如下: 三张表的关系为: 现有的测试数据为: 我们需要的结果是: 复制代码 代码如下: DECLARE @strSQL VARCHAR(8000) SET @strSQL = 'SELECT t.STUNAME [姓名]' SELECT @strSQL = @strSQL + ',SUM(CASE s.SNAME WHEN ''' + SNAME + ''' THEN g.[Score] END) [' + SNAME + ']' FROM (SELECT SNAME FROM

  • mssql 数据库表行转列,列转行终极方案

    复制代码 代码如下: --行转列问题 --建立測試環境 Create Table TEST (DATES Varchar(6), EMPNO Varchar(5), STYPE Varchar(1), AMOUNT Int) --插入數據 Insert TEST Select '200605', '02436', 'A', 5 Union All Select '200605', '02436', 'B', 3 Union All Select '200605', '02436', 'C', 3

  • mysql 行转列和列转行实例详解

    mysql行转列.列转行 语句不难,不做多余解释了,看语句时,从内往外一句一句剖析 行转列 有如图所示的表,现在希望查询的结果将行转成列 建表语句如下: CREATE TABLE `TEST_TB_GRADE` ( `ID` int(10) NOT NULL AUTO_INCREMENT, `USER_NAME` varchar(20) DEFAULT NULL, `COURSE` varchar(20) DEFAULT NULL, `SCORE` float DEFAULT '0', PRIM

  • SQL查询语句行转列横向显示实例解析

    本文分享了两个有关SQL查询语句行转列横向显示的示例,供大家参考,具体内容如下 示例1: 在SQL查询语句行转列横向显示中access中没有CASE,要用IIF代替 select  iif(sex= '1 ', '男 ', '女 ')  from  tablename select country, sum(case when type='A' then money end) as A, sum(case when type='B' then money end) as B, sum(case

  • SQLServer行转列实现思路记录

    最近面试遇到了一道面试题,顿时有点迷糊,只说出了思路,后来百度了一下,整理了一下思路,于是记录下来,方便以后学习.(面试题请参见附件) 相关的数据表: 1.Score表  2.[User]表  SQL语句如下: --方法一:静态SQL 复制代码 代码如下: SELECT * FROM (SELECT UID,Name, Score,ScoreName FROM Score,[User] WHERE Score.UID=[User].ID) AS SourceTable PIVOT(AVG(Sco

  • sql语句实现行转列的3种方法实例

    前言 一般在做数据统计的时候会用到行转列,假如要统计学生的成绩,数据库里查询出来的会是这样的,但这并不能达到想要的效果,所以要在查询的时候做一下处理,下面话不多说了,来一起看看详细的介绍. CREATE TABLE TestTable( [Id] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](50) NULL, [Subject] [nvarchar](50) NULL, [Source] [numeric](18, 0) NULL )

  • MySQL存储过程中使用动态行转列

    本文介绍的实例成功的实现了动态行转列.下面我以一个简单的数据库为例子,说明一下. 数据表结构 这里我用一个比较简单的例子来说明,也是行转列的经典例子,就是学生的成绩 三张表:学生表.课程表.成绩表 学生表 就简单一点,学生学号.学生姓名两个字段 CREATE TABLE `student` ( `stuid` VARCHAR(16) NOT NULL COMMENT '学号', `stunm` VARCHAR(20) NOT NULL COMMENT '学生姓名', PRIMARY KEY (`

  • sql动态行转列的两种方法

    第一种方法: 复制代码 代码如下: select *from ( select Url,case  when  Month=01 then  '1月' when  Month=02 then '2月' when  Month=03 then  '3月' when  Month=04 then '4月' when  Month=05 then  '5月' when  Month=06 then '6月' when  Month=07 then  '7月' when  Month=08 then '

随机推荐