关键字:    行专列,列转行, pivot, unpivot

行列转换是在数据分析中经常用到的一项功能,KingbaseES从V8R6C3B0071版本开始通过扩展插件(kdb_utils_function)支持了pivot和unpivot功能。在之前的版本如果需要进行行列转换操作要如何处理呢?下面介绍通用的写法,最后再介绍pivot和unpivot 用法。

一、行转列(pivot)

构造数据:

create table pivot_t1(month integer,fruitname text,quantity integer);

insert into pivot_t1 values(1,'apple',1000);
insert into pivot_t1 values(2,'apple',2000);
insert into pivot_t1 values(3,'apple',3000);
insert into pivot_t1 values(4,'apple',4000);
insert into pivot_t1 values(1,'orange',1500);
insert into pivot_t1 values(2,'orange',2500);
insert into pivot_t1 values(3,'orange',3500);
insert into pivot_t1 values(4,'orange',4500);
insert into pivot_t1 values(1,'grape',1800);
insert into pivot_t1 values(2,'grape',2800);
insert into pivot_t1 values(3,'grape',3800);
insert into pivot_t1 values(4,'grape',4800);
insert into pivot_t1 values(1,'banana',1600);
insert into pivot_t1 values(2,'banana',2600);
insert into pivot_t1 values(3,'banana',3600);
insert into pivot_t1 values(4,'banana',4600);

1. case when语法

test=# select month,
test-# sum(case fruitname when 'apple' then quantity end) as apple,
test-# sum(case fruitname when 'orange' then quantity end) as orange,
test-# sum(case fruitname when 'grape' then quantity end) as grape,
test-# sum(case fruitname when 'banana' then quantity end) as banana
test-# from pivot_t1 group by month order by 1;

month | apple | orange | grape | banana
-------+-----------+------------+----------+--------
1 | 1000 | 1500 | 1800 | 1600
2 | 2000 | 2500 | 2800 | 2600
3 | 3000 | 3500 | 3800 | 3600
4 | 4000 | 4500 | 4800 | 4600
(4 rows)

2. CROSSTAB语法

crosstab() 函数由 tablefunc扩展包提供。

安装扩展 create extension tablefunc;

test=# \df crosstab
函数列表
架构模式 | 名称 | 结果数据类型 | 参数数据类型 | 类型
----------+----------+--------------+---------------+------
public | crosstab | SETOF record | text | 函数
public | crosstab | SETOF record | text, integer | 函数
public | crosstab | SETOF record | text, text | 函数 

函数说明:

crosstab ( sql text ) :生成一个“数据透视表”,其中包含行名称和 N 列值,其中 N 由调用查询中指定的行类型决定。

crosstab ( source_sql text, category_sql text ) :产生一个“数据透视表”,其值列由第二个查询指定。

crosstab ( sql text, N integer ) :crosstab(text)的废弃版本。

test=# SELECT *
test-# FROM crosstab(
test(# 'select month,fruitname,quantity
test'# from pivot_t1 order by 1,2','select distinct fruitname from pivot_t1 order by 1')
test-# AS (month int, apple varchar, banana varchar, grape varchar, orange varchar); month | apple | banana | grape | orange
-------+-------+--------+-------+--------
1 | 1000 | 1600 | 1800 | 1500
2 | 2000 | 2600 | 2800 | 2500
3 | 3000 | 3600 | 3800 | 3500
4 | 4000 | 4600 | 4800 | 4500 

crosstab() 关键点:

第一个参数,带有按X,Y汇总的SQL子句,返回X,Y,Value格式的数据集;

第二个参数,SQL子句,返回用于水平表头中透视内容的所有值;

使用AS子句明确指定返回的每一个字段名称和类型,子句中列名需要与第二个参数order by结果一一对应。

3. pivot 语法:

test3=# select * from (select month,fruitname,quantity from pivot_t1)
test3-# pivot(sum(quantity) for fruitname in ('banana','apple' ,'orange','grape')); month | banana | apple | orange | grape
-------+--------+-------+--------+-------
1 | 1600 | 1000 | 1500 | 1800
2 | 2600 | 2000 | 2500 | 2800
3 | 3600 | 3000 | 3500 | 3800
4 | 4600 | 4000 | 4500 | 4800 (4 行记录)

pivot 计算指定的聚合值( sum(quantity) ),但是pivot 不包含显示的group by子句,pivot 隐式group by 是基于所有没在pivot子句中引用的列(month),以及在pivot in子句中指定的一组值。

二、列转行(unpivot)

构造数据:

create table unpivot_t1(fruitname text,q1 integer,q2 integer,q3 integer,q4 integer);
insert into unpivot_t1 values('apple', 1100,1200,1300,1400);
insert into unpivot_t1 values('orange',2100,2200,2300,null);
insert into unpivot_t1 values('grape', 3100,null,3300,3400);
insert into unpivot_t1 values('banana',4100,4200,4300,4400);

1.union all 语法

test=# select fruitname,'q1',q1 from unpivot_t1
test-# union all
test-# select fruitname,'q2',q2 from unpivot_t1
test-# union all
test-# select fruitname,'q3',q3 from unpivot_t1
test-# union all
test-# select fruitname,'q4',q4 from unpivot_t1; fruitname | ?COLUMN? | q1
-----------+----------+------
apple | q1 | 1100
orange | q1 | 2100
grape | q1 | 3100
banana | q1 | 4100
apple | q2 | 1200
orange | q2 | 2200
grape | q2 |
banana | q2 | 4200
apple | q3 | 1300
orange | q3 | 2300
grape | q3 | 3300
banana | q3 | 4300
apple | q4 | 1400
orange | q4 |
grape | q4 | 3400
banana | q4 | 4400 (16 rows)

  

2. unnest 函数

Unnest:将一个数组分解成一组行。

test=# select fruitname,unnest(array['q1','q2','q3','q4']),unnest(array[q1,q2,q3,q4]) from unpivot_t1
fruitname | unnest | unnest
-----------+--------+--------
apple | q1 | 1100
apple | q2 | 1200
apple | q3 | 1300
apple | q4 | 1400
orange | q1 | 2100
orange | q2 | 2200
orange | q3 | 2300
orange | q4 |
grape | q1 | 3100
grape | q2 |
grape | q3 | 3300
grape | q4 | 3400
banana | q1 | 4100
banana | q2 | 4200
banana | q3 | 4300
banana | q4 | 4400

  

3. unpivot 语法

test=# select fruitname,month,quantity from unpivot_t1 unpivot include nulls

test-# (quantity for month in (q1 as 'Q1',q2 as 'Q2',q3 as 'Q3',q4 as 'Q4')) order by fruitname,month;
fruitname | month | quantity
-----------+-------+----------
apple | Q1 | 1100
apple | Q2 | 1200
apple | Q3 | 1300
apple | Q4 | 1400
banana | Q1 | 4100
banana | Q2 | 4200
banana | Q3 | 4300
banana | Q4 | 4400
grape | Q1 | 3100
grape | Q2 |
grape | Q3 | 3300
grape | Q4 | 3400
orange | Q1 | 2100
orange | Q2 | 2200
orange | Q3 | 2300
orange | Q4 |
(16 行记录)

  

参考文档:

[应用开发及迁移][服务器编程]SQL语言

KingbaseES 行列转换函数的更多相关文章

  1. oracle行列转换函数的使用

    oracle 10g wmsys.wm_concat行列转换函数的使用: 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行 ...

  2. oracle 行列转换函数之WM_CONCAT和LISTAGG的使用(一)

    一.wm_concat函数 wm_concat能够实现同样的功能,但是有时在11g中使用需要用to_char()进行转换,否则会出现不兼容现象(WMSYS.WM_CONCAT: 依赖WMSYS 用户, ...

  3. Oracle 行列转换函数pivot、unpivot的使用(二)

    一.行转列pivot 关键函数pivot,其用法如下 pivot(聚合函数 for 列名 in(类型)) select * from table_name pivot(max(column_name) ...

  4. Oracle11g 行列转换函数PIVOT and UNPIVOT

    作为Oracle开发工程师,推荐大伙看看 PIVOT and UNPIVOT Operators in Oracle Database 11g Release 1 This article shows ...

  5. Oracle行列转换

    一.建表与插入数据 1.1.建表 create table kecheng ( id NUMBER, name ), course ), score NUMBER ); insert into kec ...

  6. Oracle学习之路-- 案例分析实现行列转换的几种方式

    注:本文使用的数据库表为oracle自带scott用户下的emp,dept等表结构. 通过一个例子来说明行列转换: 需求:查询每个部门中各个职位的总工资 按我们最原始的思路可能会这么写:       ...

  7. SQL Server中行列转换 Pivot UnPivot

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  8. SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例,合并列的例子

    使用过SQL Server 2000的人都知道,要想实现行列转换,必须综合利用聚合函数和动态SQL,具体实现起来需要一定的技巧,而在SQL Server 2005中,使用新引进的关键字PIVOT/UN ...

  9. SQL SERVER 合并重复行,行列转换

    引用自:http://www.cnblogs.com/love-summer/archive/2012/03/27/2419778.html sql server2000 里面如何实现oracle10 ...

随机推荐

  1. SAP Web Dynpro-监视应用程序

    您可以使用ABAP监视器来监视Web Dynpro应用程序. 存储有关Web Dynpro应用程序的信息. 您可以使用T代码-RZ20查看此信息. 您可以在Web Dynpro ABAP监视器中查看以 ...

  2. 158_模型_Power BI 使用 DAX + SVG 打通制作商业图表几乎所有可能

    158_模型_Power BI 使用 DAX + SVG 打通制作商业图表几乎所有可能 一.背景 最近对 Power BI 中使用 SVG 比较感兴趣,今天我们使用 DAX + SVG 复刻一下 Ze ...

  3. 全国气象数据/降雨量分布数据/太阳辐射数据/NPP净初级生产力数据/植被覆盖度数据

    ​        气象数据一直是一个价值较高的数据,它被广泛用于各个领域的研究当中.气象数据包括有气温.气压.相对湿度.降水.蒸发.风向风速.日照等多种指标,但是包含了这些全部指标的气象数据却较难获取 ...

  4. 螣龙安科:威胁研究——与MAZE勒索软件事件相关的策略,技术和程序

    至少从2019年5月开始,恶意行为者就一直在积极部署MAZE勒索软件.勒索软件最初是通过垃圾邮件和漏洞利用工具包分发的,后来又转移到妥协后进行部署.根据我们在地下论坛中对涉嫌用户的观察以及整个Mand ...

  5. java.Scanner 拓展用法

    package study5ran2yl.study; import java.util.Scanner; public class demo11 { public static void main( ...

  6. java -jar -Xbootclasspath/a:/xxx/config xxx .jar 和 java -jar xxx .jar 的区别

    1.如果有用Xbootclasspath的话则config的文件会直接覆盖jar里面的resouces文件,覆盖application.yml ,也会覆盖logback-spring.xml ,比如j ...

  7. Webpack干货系列 | 在 Webpack 5 集成 ESLint 的方法

    程序员优雅哥(youyacoder)简介:十年程序员,呆过央企外企私企,做过前端后端架构.分享vue.Java等前后端技术和架构. 本文摘要:主要讲解运用Webpack 5 中集成 ESLint 的方 ...

  8. Blazor快速实现扫雷(MineSweeper)

    如何快速的实现一个扫雷呢,最好的办法不是从头写,而是移植一个已经写好的! Blazor出来时间也不短了,作为一个.net开发者就用它来作吧.Blazor给我的感觉像是Angular和React的结合体 ...

  9. python 部分内置函数详解

    简介 eval与exec eval和exec都是python内置的可以执行python代码的函数,但它们之间有所区别. eval(expression[, globals[, locals]]) ex ...

  10. Linux—搭建Apache(httpd)服务

    1.httpd简介? http是Apache超文本传输协议服务器的主程序.它是一个独立的后台进程,能够处理请求的子进程和线程. http常用用的两个版本是httpd-2.2和httpd-2.4 Cen ...