百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

sql写法之数据透视(行转列及列转行)

sinye56 2024-10-01 20:19 3 浏览 0 评论

/*pivot 行转列*/

/*

<left_table_expression>

PIVOT (<aggregate_func(<aggregation_element>)> FOR

<spreading_element> IN(<target_col_list>))

AS <result_table_alias>

--显示指定的元素(PIVOT运算符的圆括号中指定的元素)

-- 聚合函数(aggregate_func)

-- 聚合元素(aggregation_element)

-- 聚合函数的输入必须是PIVOT运算符的输入表中未处理的基列,不能是表达式

-- 如果想为聚合函数提供一个表达式作为输入,可以现在派生表或CTE中进行处理,再让PIVOT运算符对派生表或CTE进行操作

-- 扩展元素(spreading_element) (For关键字后面的列)

-- 透视转换不能扩展多个列的属性

-- 如果需要对多个列进行扩展,可以在表表达式中先进行联接处理,再应用PIVOT运算符

-- 扩展值(target_col_list)

-- 与扩展元素对应的列值

--隐含的元素

-- 分组元素

-- 分组元素隐含出自那些没有指定的属性(PIVOT运算符的分组元素是输入表的所有列中,既没有指定为聚合元素,也没有指定为扩展元素的那些列。)

*/

/*mss和ora在语法上的区别*/

/*初始化表结构*/

create table hp1 (id int,name varchar(10))

insert into hp1(id,name)

values(1,'a'),(1,'b'),(2,'a'),(3,'c'),(4,'b'),(4,'d'),(3,'1'),(3,'2');

/*sql server*/

with tbl as

( select * from

(select id,name,1 as col from hp1) t pivot(max(col) for name in ([a],[b]) ) p

)

select * from tbl where [a] = 1 and [b] = 1 ;

/*oracle11g*/

with tbl as

( select * from

(select id,name,1 as col from hp1) t pivot(max(col) for name in ('a','b') ) p

)

select * from tbl where "'a'" = 1 and "'b'" = 1 ;

/*应用举例:统计每个客户在2014年和2015年的消费金额*/

create table hpOrders

(OrderID int,

OrderDate date,

OrderYear varchar(4),

OrderMonth varchar(2),

CustomerID int,

TotalValue decimal(20,8)

);

/*Sql Server,准备数据*/

with t as

(

select top 1000 row_number() over(order by id) rn

from sysobjects

order by rn

)

insert into hpOrders(OrderID,OrderDate,OrderYear,OrderMonth,CustomerID,TotalValue)

select rn, dateadd(DAY,-1 * (rn%300), getdate()),

year(dateadd(DAY,-1 * (rn%300), getdate())),

right('0' + cast(month(dateadd(DAY,-1 * (rn%300), getdate())) as varchar(2)),2),

rn%10, rn

from t ;

/*应用举例:统计每个客户在2014年和2015年的消费金额*/

/*PIVOT: Sql Server*/

select * from

(select CustomerID,OrderYear,TotalValue from hpOrders) t

pivot(sum(TotalValue) for OrderYear in ([2014],[2015])) p ;

/*准备数据:oracle*/

insert into hpOrders(OrderID,OrderDate,OrderYear,OrderMonth,CustomerID,TotalValue)

select rownum, sysdate - mod(level,300),

to_char(sysdate - mod(level,300),'yyyy'),

to_char(sysdate - mod(level,300),'mm'),

mod(level,10), level

from dual

connect by level <= 1000;

/*应用举例:统计每个客户在2014年和2015年的消费金额*/

/*PIVOT: oracle11g*/

select * from

(select CustomerID,OrderYear,TotalValue from hpOrders) t

pivot(sum(TotalValue) for OrderYear in ('2014' as Y2014,'2015' as Y2015)) p ;

/*PIVOT: oracle10g*/

select CustomerID,

sum(decode(OrderYear,'2014',TotalValue,0)) as Y2014,

sum(decode(OrderYear,'2014',TotalValue,0)) as Y2015

from hpOrders

group by CustomerID;

/*逆透视 unpivot 列转行

语法

<left_table_expression>

UNPIVOT (<target_values_col> FOR

<target_names_col> IN(<source_col_list>))

AS <result_table_alias>

-- UNPIVOT运算符比PIVOT运算符更简单和直观

-- UNPIVOT的第一个输入是用于保存源表列值的目标列名称<target_values_col>

-- For关键字后面指定用于保存源表列名的目标列名称<target_names_col>

-- IN子句中的圆括号中指定要进行逆透视转换的源表列名(<source_col_list>) --比如比如([2006],[2007],[2008])

*/

/*为每个客户和每个年份生成结果集中的一行,每行包括客户id,订单年份和订货量*/

/*Sql Server*/

select CustomerID,

coalesce([2014], 0) as [2014],

coalesce([2015], 0) as [2015]

into hpOrders1

from

(select CustomerID,OrderYear,TotalValue from hpOrders) t

pivot(sum(TotalValue) for OrderYear in ([2014],[2015])) p ;

select * from hpOrders1;

go

/*列转行:使用cross join子句*/

select CustomerID, OrderYear, TotalValue

from (select CustomerID, OrderYear,

case OrderYear

when 2014 then [2014]

when 2015 then [2015]

end as TotalValue

from hpOrders1

cross join /*为各年度创建副本*/

(select 2014 as orderyear

union all select 2015) as orderyears

) as y

where TotalValue is not null;

/*列转行:使用cross join+values子句*/

select CustomerID, OrderYear, TotalValue

from (select CustomerID, OrderYear,

case OrderYear

when 2014 then [2014]

when 2015 then [2015]

end as TotalValue

from hpOrders1

cross join /*sql server2008可将union all转换为values子句,2005及之前的版本不支持该子句*/

(values(2014),(2015)) as orderyears(orderyear)) as y

where TotalValue is not null;

/*列转行:unpivot*/

select CustomerID, OrderYear, TotalValue

from hpOrders1

unpivot(TotalValue for OrderYear in([2014],[2015])) as u;

go

drop table hpOrders1;

drop table hpOrders;

drop table hp1;

相关推荐

linux安装FTP

1、在nkftp目录下安装ftp,进入到nkftp里面[root@localhostbin]#cd/data/nkftp执行安装命令:[root@localhostnkftp]#rpm-i...

LINUX下搭建FTP服务器

FTP服务器介绍FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(App...

Linux下如何进行FTP设置

目录:一、Redhat/CentOS安装vsftp软件二、Ubuntu/Debian安装vsftp软件一、Redhat/CentOS安装vsftp软件1.更新yum源yumupdate-y2.安...

推荐使用集串口 SSH远程登录和FTP传输三合一工具MobaXterm

来源:百问网作者:韦东山本文字数:1216,阅读时长:4分钟在以前的资料里,串口和SSH远程登使用SecureCRT,window与ubuntu数据传输使用filezilla,窗口切换来切换去,麻烦也...

如何搭建FTP服务器(Linux系统)

上次说了Windows操作系统下搭建的FTP服务器,那有朋友问我,说买的XX轻量应用服务器都是属于Linux的操作系统,我该如何为搭建FTP服务器呢?...

Linux 命令 ncftp(文件传输)——想玩转linux就请一直看下去

我是IT悟道,点击右上方“关注”,每天分享IT、科技、数码方面的干货。Linuxncftp命令...

如何用 ftp 实现一键上传

简介ftp是Internet标准文件传输协议的用户界面,它允许用户与远程网络站点之间传输文件...

Linux安装ftp

1安装vsftpd组件安装完后,有/etc/vsftpd/vsftpd.conf文件,是vsftp的配置文件。[root@bogon~]#yum-yinstallvsftpd2添加一个...

一天一点点:linux - ftp命令

linuxftp命令设置文件系统相关功能。FTP是ARPANet的标准文件传输协议,该网络就是现今Internet的前身。语法ftp[-dignv][主机名称或IP地址]参数:-d详细显示指令执...

Centos 7 搭建FTP

目录安装软件以及启动服务添加防火墙规则关闭selinuxftp配置常用常用参数详解特殊参数配置文件没有的参数也可以添加到配置中1.安装软件以及启动服务yuminstall-yvsftpdsys...

【Linux】Linux中ftp命令,没有你想的那么简单

本文介绍了Linux中FTP命令的基本用法,包括连接与登录远程服务器,以及解析了FTP协议中五个最常用的操作命令的使用和解析过程。同时,提供了一个包含常用FTP操作命令的表格,供读者参考。通过熟练掌握...

linux 命令行操作ftp

以下是linuxftp命令参数的详解。FTP>!从ftp子系统退出到外壳?FTP>?显示ftp命令说明??和help相同?格式:?[command]说明:[com...

多学习才能多赚钱之:linux如何使用ftp

linux如何使用ftp步骤1:建立FTP连接想要连接FTP服务器,在命令上中先输入ftp然后空格跟上FTP服务器的域名'domain.com'或者IP地址例如:ftpdom...

linux常用网络操作方法:ftp命令使用方法

常用网络操作方法Linux提供了一组强有力的网络命令来为用户服务,这些工具能够帮助用户登录到远程计算机上、传输文件和执行远程命令等。本节介绍下列几个常用的有关网络操作的命令:ftp传输文件tel...

Linux 5.15有望合并Memory Folios方案 内核构建速度可提升7%

甲骨文公司的长期内核开发人员MatthewWilcox已经研究了“内存对开区”概念相当长的一段时间,这可以改善Linux的内存管理,使其具有更大的效率。例如,使用内存对开的基准测试表明,内核的构建速...

取消回复欢迎 发表评论: