KingbaseES 行列轉換函數


關鍵字:    行專列,列轉行, 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語言

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM