行转列的一个SQL写法(以Oracle为例)

简介:

在数据分析的过程中,常常会遇到行转列的问题。例如,系统按事务逐条摆放,但是分析时希望以某个线索(例如每一个客户)为中心,查看所有的事项。写个性化程序或者写自定义聚合函数都可以有很好的解决方案,但是计算环境复杂多变,有程序未必能部署上,掌握一个SQL写法快速响应大多数分析场景还是很有必要的。本文以Oracle为例,主要使用了row_number函数(不使用rank函数的原因是不希望出现2条记录排名相同的情况,我们的最终目的是行转列,不是合理排名)

下列sql准备一下测试数据:

 
  1. -- drop table example_row_data;  
  2.  
  3. create table example_row_data (  
  4.        user_school varchar2(2000),  
  5.        user_name varchar2(2000),  
  6.        user_item varchar2(2000),  
  7.        user_value number         
  8. );  
  9.  
  10. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_1','Linux',20);  
  11. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_1','BI',2);  
  12. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_1','数据库',20);  
  13. commit;  
  14. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_2','Linux',10);  
  15. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_2','BI',30);  
  16. commit;  
  17. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_3','Linux',5);  
  18. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_3','BI',2);  
  19. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_3','数据库',6);  
  20. insert into example_row_data(user_school,user_name,user_item,user_value) values('博客','iData_3','数据挖掘',20);  
  21. commit

 查看样例数据:

 
  1. SQL> select substr(t.user_school,1,4) 类别,substr(user_name,1,8) 用户 ,substr(t.user_item,1,8) 科目,substr(t.user_value,1,2) 数值 from example_row_data t;  
  2.    
  3. 类别     用户             科目             数值  
  4. -------- ---------------- ---------------- ----  
  5. 博客     iData_1          Linux            20  
  6. 博客     iData_1          BI               2  
  7. 博客     iData_1          数据库           20  
  8. 博客     iData_2          Linux            10  
  9. 博客     iData_2          BI               30  
  10. 博客     iData_3          Linux            5  
  11. 博客     iData_3          BI               2  
  12. 博客     iData_3          数据库           6  
  13. 博客     iData_3          数据挖掘         20  
  14.    
  15. rows selected 

行转列前的准备工作,计算单个用户最大可能的科目数:

 
  1. SQL> SELECT MAX(cnt)  
  2.   2  FROM   (SELECT t.user_school  
  3.   3                ,t.user_name  
  4.   4                ,COUNT(*) cnt  
  5.   5          FROM   example_row_data t  
  6.   6          GROUP  BY t.user_school  
  7.   7                   ,t.user_name) t;  
  8.    
  9.   MAX(CNT)  
  10. ----------  
  11.          4 

行转列(已知最大科目数为4):

 
  1. SELECT substr(t.user_school, 1, 4) 类别  
  2.       ,substr(t.user_name, 1, 8) 用户  
  3.       ,MAX(decode(rk, 1, rpad(t.user_item || ':' || t.user_value, 14, ' '), NULL)) ||  
  4.        MAX(decode(rk, 2, rpad(t.user_item || ':' || t.user_value, 14, ' '), NULL)) ||  
  5.        MAX(decode(rk, 3, rpad(t.user_item || ':' || t.user_value, 14, ' '), NULL)) ||  
  6.        MAX(decode(rk, 4, rpad(t.user_item || ':' || t.user_value, 14, ' '), NULL)) 科目成绩  
  7. FROM   (SELECT t.*  
  8.               ,row_number() over(PARTITION BY t.user_school, t.user_name ORDER BY t.user_item) rk  
  9.         FROM   example_row_data t) t  
  10. GROUP  BY t.user_school  
  11.          ,t.user_name;  
  12.  
  13. 类别     用户             科目成绩  
  14. -------- ---------------- ---------------------------------------------------  
  15. 博客     iData_1          BI:2          Linux:20      数据库:20  
  16. 博客     iData_2          BI:30         Linux:10  
  17. 博客     iData_3          BI:2          Linux:5       数据库:6      数据挖掘:20 



本文转自 hexiaini235 51CTO博客,原文链接:http://blog.51cto.com/idata/1071030 ,如需转载请自行联系原作者

相关文章
|
5月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
409 8
|
10月前
|
SQL Oracle 关系型数据库
解决大小写、保留字与特殊字符问题!Oracle双引号在SQL中的特殊应用
在Oracle数据库开发中,双引号的使用是一个重要但易被忽视的细节。本文全面解析了双引号在SQL中的特殊应用场景,包括解决标识符与保留字冲突、强制保留大小写、支持特殊字符和数字开头标识符等。同时提供了最佳实践建议,帮助开发者规避常见错误,提高代码可维护性和效率。
406 6
|
11月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
11月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
|
11月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
|
SQL Oracle 关系型数据库
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
|
SQL 监控 Oracle
Oracle SQL性能优化全面指南
在数据库管理领域,Oracle SQL性能优化是确保数据库高效运行和数据查询速度的关键
1700 6
|
SQL 关系型数据库 Oracle
ORACLE SQL优化之ORA-03150&ORA-02055&ORA-02063
                                                                                                             >   
5107 0
|
SQL Oracle 关系型数据库
Oracle SQL优化之多表连接
Oracle SQL优化之多表连接
844 0
Oracle SQL优化之多表连接
|
SQL 存储 Oracle
Oracle数据库 | SQL语句执行计划、语句跟踪与优化实例
Oracle数据库 | SQL语句执行计划、语句跟踪与优化实例
527 0

推荐镜像

更多