法一: crosstab

原表(左)及现实结果表(右)展示:

第一步:  安装扩展

create extension tablefunc;

** 否则后续会报错

错误:  函数 crosstab(unknown, unknown) 不存在

第二步: 对表进行空值处理(此处将空值填写为字符串'空值')

update t_user_income set income='空值' where income is null;

目的: 有效区分哪些数据 "原表里是空值" 及 "原表没有该行数据"

以员工号:24753122 6月份数据为例(左图红框):

6月1-12日原表中没有数据,

6月13日有该记录但为空值(判空处理前为NULL)

处理结果为右图:

结果表能轻易得出, 绿框表示原本无数据, 红框为有记录但income值为NULL

** 如不需区分可直接跳过这一步

第三步: 行专列(crosstab函数)

 select (regexp_split_to_array(id,','))[1] as emp_no, --转为数组并取[1]员工编号(regexp_split_to_array(id,','))[2] as ny,     --转为数组并取[2]年月D01,D02,D03,D04,D05,D06,D07,D08,D09,D10,D11,D12,D13,D14,D15,D16,D17,D18,D19,D20,D21,D22,D23,D24,D25,D26,D27,D28,D29,D30,D31 --日期from( select * from crosstab('select concat_ws('','',emp_no,to_char(tjsj,''yyyymm'')) as id, to_char(tjsj,''dd'') as tjsj, income::varchar from t_user_income order by 1','select distinct to_char(tjsj,''dd'') as tjsj from t_user_income order by 1')as ct(id varchar(50000),D01 varchar(500),D02 varchar(500),D03 varchar(500),D04 varchar(500),D05 varchar(500),D06 varchar(500),D07 varchar(500),D08 varchar(500),D09 varchar(500),D10 varchar(500),D11 varchar(500),D12 varchar(500),D13 varchar(500),D14 varchar(500),D15 varchar(500),D16 varchar(500),D17 varchar(500),D18 varchar(500),D19 varchar(500),D20 varchar(500),D21 varchar(500),D22 varchar(500),D23 varchar(500),D24 varchar(500),D25 varchar(500),D26 varchar(500),D27 varchar(500),D28 varchar(500),D29 varchar(500),D30 varchar(500),D31 varchar(500)))border by emp_no, ny

 第三步拆解:

A拆解 :

select concat_ws(',',emp_no,to_char(tjsj,'yyyymm')) as id, to_char(tjsj,'dd') as tjsj, income::varchar from t_user_income order by 1

1- 选择要转置的列: (SELECT 列名[对应红框], 列名[对应绿框], 值[对应橙框] FROM TABLE): 

此处为

列名 [ 红框 ]: concat_ws(',',emp_no,to_char(tjsj,'yyyymm')) as id

列名 [ 绿框 ]: to_char(tjsj,'dd') as tjsj

值 [ 橙框 ]: income::varchar

左侧是A运行结果, 对应右侧的结果集

2- 值: 数据类型必须一致

因此此处income提前转为varchar

B拆解

select distinct to_char(tjsj,'dd') as tjsj from t_user_income order by 1

1- SELECT 列名[转置的列] FROM TABLE 

2- 结果行必须与结果展示的列一致

 

C拆解

可见C步骤后 ID列不是我们最终想要的结果, 因此在最外嵌套一层把ID列拆成emp_no 及 ny列即可

 (regexp_split_to_array(id,','))[1] as emp_no, --转为数组并取[1]员工编号(regexp_split_to_array(id,','))[2] as ny,     --转为数组并取[2]年月

法二: 模块 - 利用INSERT

N天后补充

法三: CASE WHEN 

例一

原表(左)及现实结果表(右)展示:

第一步: 先按照科目分开, 符合条件的设置分数,不符合的给置零

select name as '姓名',(case course when '语文' then score else 0 end) as '语文',(case course when '数学' then score else 0 end) as '数学',(case course when '英语' then score else 0 end) as '英语'
from course_score

第二步: 然后再按照名字group by ,对分数求max

select name as '姓名',max(语文) as '语文',max(数学) as '数学',max(英语) as '英语'
from (select name as '姓名',(case course when '语文' then score else 0 end) as '语文',(case course when '数学' then score else 0 end) as '数学',(case course when '英语' then score else 0 end) as '英语'from course_score) s
group by name;

例二 (crosstab方法的例子)

select emp_no,ny,
max(D01) as D01,
max(D02) as D02,
max(D03) as D03,
max(D04) as D04,
max(D05) as D05,
max(D06) as D06,
max(D07) as D07,
max(D08) as D08,
max(D09) as D09,
max(D10) as D10,
max(D11) as D11,
max(D12) as D12,
max(D13) as D13,
max(D14) as D14,
max(D15) as D15,
max(D16) as D16,
max(D17) as D17,
max(D18) as D18,
max(D19) as D19,
max(D20) as D20,
max(D21) as D21,
max(D22) as D22,
max(D23) as D23,
max(D24) as D24,
max(D25) as D25,
max(D26) as D26,
max(D27) as D27,
max(D28) as D28,
max(D29) as D29,
max(D30) as D30,
max(D31) as D31
from(select emp_no,to_char(tjsj, 'yyyymm') as ny,case when to_char(tjsj,'dd')='01' then income::varchar else 0::varchar end as D01,case when to_char(tjsj,'dd')='02' then income::varchar else 0::varchar end as D02,case when to_char(tjsj,'dd')='03' then income::varchar else 0::varchar end as D03,case when to_char(tjsj,'dd')='04' then income::varchar else 0::varchar end as D04,case when to_char(tjsj,'dd')='05' then income::varchar else 0::varchar end as D05,case when to_char(tjsj,'dd')='06' then income::varchar else 0::varchar end as D06,case when to_char(tjsj,'dd')='07' then income::varchar else 0::varchar end as D07,case when to_char(tjsj,'dd')='08' then income::varchar else 0::varchar end as D08,case when to_char(tjsj,'dd')='09' then income::varchar else 0::varchar end as D09,case when to_char(tjsj,'dd')='10' then income::varchar else 0::varchar end as D10,case when to_char(tjsj,'dd')='11' then income::varchar else 0::varchar end as D11,case when to_char(tjsj,'dd')='12' then income::varchar else 0::varchar end as D12,case when to_char(tjsj,'dd')='13' then income::varchar else 0::varchar end as D13,case when to_char(tjsj,'dd')='14' then income::varchar else 0::varchar end as D14,case when to_char(tjsj,'dd')='15' then income::varchar else 0::varchar end as D15,case when to_char(tjsj,'dd')='16' then income::varchar else 0::varchar end as D16,case when to_char(tjsj,'dd')='17' then income::varchar else 0::varchar end as D17,case when to_char(tjsj,'dd')='18' then income::varchar else 0::varchar end as D18,case when to_char(tjsj,'dd')='19' then income::varchar else 0::varchar end as D19,case when to_char(tjsj,'dd')='20' then income::varchar else 0::varchar end as D20,case when to_char(tjsj,'dd')='21' then income::varchar else 0::varchar end as D21,case when to_char(tjsj,'dd')='22' then income::varchar else 0::varchar end as D22,case when to_char(tjsj,'dd')='23' then income::varchar else 0::varchar end as D23,case when to_char(tjsj,'dd')='24' then income::varchar else 0::varchar end as D24,case when to_char(tjsj,'dd')='25' then income::varchar else 0::varchar end as D25,case when to_char(tjsj,'dd')='26' then income::varchar else 0::varchar end as D26,case when to_char(tjsj,'dd')='27' then income::varchar else 0::varchar end as D27,case when to_char(tjsj,'dd')='28' then income::varchar else 0::varchar end as D28,case when to_char(tjsj,'dd')='29' then income::varchar else 0::varchar end as D29,case when to_char(tjsj,'dd')='30' then income::varchar else 0::varchar end as D30,case when to_char(tjsj,'dd')='31' then income::varchar else 0::varchar end as D31from t_user_income)a group by  emp_no,nyorder by emp_no,ny

文档来源:

PostgreSQL: Documentation: 11: F.38. tablefunc

PostgreSQL 行转列相关推荐

  1. matlab 列转行,postgresql 行转列,列转行后加入到一个整体数据

    这里行转列的基本思想就是使用max,因为其他列下面都是NULL,所以可以Max最后就只能得到有值的这行 普通的查询: SELECT icd , case when (ROW_NUMBER() OVER ...

  2. postgresql行转列、列转行

    列转行 postgresql列转行的思路主要是利用string_to_array进行数组转换,然后用unnest进行行拆分 select t.bid_unit,unit_id from unit t ...

  3. PostgreSQL 行变列的小应用

    为什么80%的码农都做不了架构师?>>>    好久没写博客了 也好久没写代码了 拿这个充充数吧 哈哈 今天在群里看到一朋友提问 问题是截图,截图如下 用PostgreSQL的cro ...

  4. PostgreSQL如何行转列

    PostgreSQL如何行转列 方法一:group by + sum + case when select name, sum(case when zbfm='年龄' then value else ...

  5. MySQL 学习笔记(16)— 子查询(单行单列、一行多列、多行多列、 ALL、ANY、SOME 运算符、EXISTS 操作符)

    1. 子查询概念 子查询是指嵌套在其他语句(SELECT . INSERT . UPDATE . DELETE 等)中的 SELECT 语句:子查询也称为内查询( inner query )或者嵌套查 ...

  6. 一次PostgreSQL行估算偏差导致的慢查询分析

    本文为DBAPlus投稿文章, 原文链接: http://dbaplus.cn/news-19-1514-1.html 一次PostgreSQL行估算偏差导致的慢查询分析 问题 最近某业务系统上线了新 ...

  7. postgresql的系统列(system cloumns)

    每种数据库中都保留了自己所有的关键字,在表的定义过程中同样数据库保存了自己的系统列.看完关于postgresql的系统列部分的文档,还勾起了我想了解postgresql事务如何进行管理的冲动.先对po ...

  8. KINGBASE V7 行转列

    KINGBASE 数据库是基于PostgreSQL内核研发的国产数据库,在应用开发过程中想使用列转行函数,发现KINGBASE V7版本没有,PostgreSQL 列转行函数试试STRING_AGG. ...

  9. 2021年大数据Hive(五):Hive的内置函数(数学、字符串、日期、条件、转换、行转列)

    全网最详细的Hive文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 系列历史文章 前言 Hive的内置函数 一.数学函数 1. 取整函数: round ...

最新文章

  1. 威尔逊定理 ---- [hdu-6608] Fansblog 威尔逊定理 质数的密度分布 快速乘优化快速幂防止中间爆longlong
  2. 汉芯一号、木兰语言再到天赐 OS,国产基础软件十年泣血,梦想何圆?
  3. Python 基础 - Day 1 Assignment - Login 模拟登陆
  4. Linux疑难杂症解决方案100篇(七)-SHELL编程变量与四则运算
  5. 52条实用经验,SQL优化不再难!
  6. 软件设计原则(三)里氏替换原则 -Liskov Substitution Principle
  7. JavaScript: Cookie 详解、实例与应用
  8. LeetCode 1854. 人口最多的年份(差分)
  9. 目标2020:'鼠'你最棒!
  10. ROS学习笔记十二:使用roswtf
  11. Airbnb 弃用之后,我们还应该用 React Native 吗?
  12. 百面机器学习—10.循环神经网络面试问题总结
  13. 键盘视频鼠标(KVM)切换器基础知识
  14. 拯救者 linux 无线网卡驱动下载,联想y7000无线网卡驱动下载-联想拯救者y7000无线网卡驱动v19.51.22.2 官方版 - 极光下载站...
  15. 自己动手搭建家庭局域网(三),千兆网+NAS存储+低成本
  16. 荧光染料 ICG-HSA 吲哚菁绿修饰人血白蛋白
  17. 静一静,做好人生的减法
  18. 单片机(中断系统-串口通信)
  19. window.print()实现分页打印
  20. 通过python-pptx模块操作ppt文件

热门文章

  1. Unity TMP字体模拟器不显示的问题和某些手机上出现不显示的问题
  2. 【数据库异常】sql-error-codes.xml
  3. 网络渗透实验一 ----------信息的搜集
  4. 戴尔灵越游匣+Ubuntu16.04的NVIDIA GTX1050显卡驱动安装.md
  5. Linux学习-Redis哨兵
  6. 映客忙着“寻找马东”,云豹直播借势移动直播开创新高度
  7. C#结合GDAL使用DataSet的ReadRaster和WriteRaster方法实现水平镜像
  8. html css视频播放效果案例
  9. JAVA压缩JS或CSS文件
  10. MCGS昆仑通态触摸屏导入博途自定义数据类型和DB块变量的具体方法演示