1. 程式人生 > >PostgreSQL 實現交叉表(行列轉換)的五種方法

PostgreSQL 實現交叉表(行列轉換)的五種方法

這裡我來演示下在POSTGRESQL裡面如何實現交叉表的展示,至於什麼是交叉表,我就不多說了,度娘去哦。
原始表資料如下:
  1. t_girl=# select * from score;  
  2.  name  | subject | score   
  3. -------+---------+-------
  4.  Lucy  | English |   100  
  5.  Lucy  | Physics |    90  
  6.  Lucy  | Math    |    85  
  7.  Lily  | English |    95  
  8.  Lily  | Physics |    81  
  9.  Lily  | Math    |    84  
  10.  David | English |   100  
  11.  David | Physics |    86  
  12.  David | Math    |    89  
  13.  Simon | English |    90  
  14.  Simon | Physics |    76  
  15.  Simon | Math    |    79  
  16. (12 rows)  
  17. Time: 2.066 ms  




想要實現以下的結果:
  1. name  | English | Physics | Math   
  2. ------+---------+---------+------
  3. Simon |      90 |      76 |   79  
  4. Lucy  |     100 |      90 |   85  
  5. Lily  |      95 |      81 |   84  
  6. David |     100 |      86 |   89  




大致有以下幾種方法:


1、用標準SQL展現出來
  1. t_girl=# selectname,   
  2. t_girl-#  sum(casewhen subject = 'English'then score else 0 endas"English",  
  3. t_girl-#  sum(casewhen subject = 'Physics'then  score else 0 endas"Physics"
    ,  
  4. t_girl-#  sum(casewhen subject = 'Math'then score else 0 endas"Math"
  5. t_girl-#  from score  
  6. t_girl-#  groupbynameorderbynamedesc;  
  7.  name  | English | Physics | Math   
  8. -------+---------+---------+------
  9.  Simon |      90 |      76 |   79  
  10.  Lucy  |     100 |      90 |   85  
  11.  Lily  |      95 |      81 |   84  
  12.  David |     100 |      86 |   89  
  13. (4 rows)  
  14. Time: 1.123 ms  




2、用PostgreSQL 提供的第三方擴充套件 tablefunc 帶來的函式實現
以下函式crosstab 裡面的SQL必須有三個欄位,name, 分類以及分類值來作為起始引數,必須以name,分類值作為輸出引數。
  1. t_girl=# SELECT *  
  2. FROM crosstab('select name,subject,score from score order by name desc',$$values ('English'::text),('Physics'::text),('Math'::text)$$)  
  3. AS score(name text, English int, Physics int, Math int);  
  4.  name  | english | physics | math   
  5. -------+---------+---------+------
  6.  Simon |      90 |      76 |   79  
  7.  Lucy  |     100 |      90 |   85  
  8.  Lily  |      95 |      81 |   84  
  9.  David |     100 |      86 |   89  
  10. (4 rows)  
  11. Time: 2.059 ms  




3、用PostgreSQL 自身的聚合函式實現

  1. t_girl=# selectname,split_part(split_part(tmp,',',1),':',2) as"English",  
  2. t_girl-# split_part(split_part(tmp,',',2),':',2) as"Physics",  
  3. t_girl-# split_part(split_part(tmp,',',3),':',2) as"Math"
  4. t_girl-# from
  5. t_girl-# (  
  6. t_girl(# selectname,string_agg(subject||':'||score,','as tmp from score groupbynameorderbynamedesc
  7. t_girl(# ) as T;  
  8.  name  | English | Physics | Math   
  9. -------+---------+---------+------
  10.  Simon | 90      | 76      | 79  
  11.  Lucy  | 100     | 90      | 85  
  12.  Lily  | 95      | 81      | 84  
  13.  David | 100     | 86      | 89  
  14. (4 rows)  
  15. Time: 2.396 ms  






4、 儲存函式實現

  1. createorreplacefunction func_ytt_crosstab_py ()  
  2. returns setof ytt_crosstab  
  3. as
  4. $ytt$  
  5.   for row in plpy.cursor("select name,string_agg(subject||':'||score,',') as tmp from score group by name order by name desc"):  
  6.       a = row['tmp'].split(',')  
  7.       yield (row['name'],a[0].split(':')[1],a[1].split(':')[1],a[2].split(':')[1])  
  8. $ytt$ language plpythonu;  
  9. t_girl=# selectname,english,physics,math from  func_ytt_crosstab_py();  
  10.  name  | english | physics | math   
  11. -------+---------+---------+------
  12.  Simon | 90      | 76      | 79  
  13.  Lucy  | 100     | 90      | 85  
  14.  Lily  | 95      | 81      | 84  
  15.  David | 100     | 86      | 89  
  16. (4 rows)  
  17. Time: 2.687 ms  




5、 用PLPGSQL來實現

  1. t_girl=# create type ytt_crosstab as (name text, English text, Physics text, Math text);  
  2. CREATE TYPE  
  3. Time: 22.518 ms  
  4. createorreplacefunction func_ytt_crosstab ()  
  5. returns setof ytt_crosstab  
  6. as
  7. $ytt$  
  8.   declare v_name text := '';  
  9.                 v_english text := '';  
  10.         v_physics text := '';  
  11.         v_math text := '';  
  12.         v_tmp_result text := '';  
  13.   declare cs1 cursorforselectname,string_agg(subject||':'||score,','from score groupbynameorderbynamedesc;  
  14. begin
  15.   open cs1;  
  16.   loop  
  17.     fetch cs1 into v_name,v_tmp_result;  
  18.     exit whennot found;  
  19.     v_english = split_part(split_part(v_tmp_result,',',1),':',2);  
  20.     v_physics = split_part(split_part(v_tmp_result,',',2),':',2);  
  21.     v_math = split_part(split_part(v_tmp_result,',',3),':',2);  
  22.     return query select v_name,v_english,v_physics,v_math;  
  23.   end loop;  
  24. end;  
  25. $ytt$ language plpgsql;  
  26. t_girl=# selectname,English,Physics,Math from func_ytt_crosstab();  
  27.  name  | english | physics | math   
  28. -------+---------+---------+------
  29.  Simon | 90      | 76      | 79  
  30.  Lucy  | 100     | 90      | 85  
  31.  Lily  | 95      | 81      | 84  
  32.  David | 100     | 86      | 89  
  33. (4 rows)  
  34. 相關推薦

    PostgreSQL 實現交叉行列轉換方法

    這裡我來演示下在POSTGRESQL裡面如何實現交叉表的展示,至於什麼是交叉表,我就不多說了,度娘去哦。原始表資料如下: t_girl=# select * from score;    name  | subject | score    -------+------

    鋒利的SQL-SQL Server的旋轉行列轉換

    所謂表旋轉,就是將表的行轉換為列,或是將表的列轉換為行,這是從SQL Server 2005開始提供的新技術。因此,如果希望使用此功能,需要將資料庫的相容級別設定為90。表旋轉在某些方面也是解決了表的資料儲存和實際需要之間的矛盾。例如,圖9-4所示的是一個典型的產品銷售統計表

    Postgresql中臨時temporary table的特性和用法

    .net 他會 acl tmp 就會 fonts 功能 不能 聲明 熟悉Oracle的人,相比對臨時表(temporary table)並不陌生,很多場景對解決問題起到不錯的作用,開源庫Postgresql中,也有臨時表的概念,雖然和Oracle中臨時表名字相同,使用方法和

    內連線、外連線、子查詢(exists用法,關聯/非關聯子查詢)、課堂練習行列轉換、rownum和rowid

    笛卡爾積 和內連線 外連線 實際上是兩張表的乘積,查詢結果沒有實際意義 select * from emp,dept; 內連線-等值內連線(隱式) select * from emp,dept where emp.deptno = dept.deptno

    使用vue實現行列轉換的一方法

         行列轉換是一個老生常談的問題,這幾天逛知乎有遇到了這個問題。一個前端說,拿到的資料是單列的需要做轉換才能夠繫結,折騰了好久才搞定,還說這個應該後端直接出資料,不應該讓前端折騰。   這個嘛,行列轉換在後端也不是很好解決的問題,而且還有一個性能的問題,綜合考慮,我還是覺得應該由前端進行行列轉換。光

    hive權威安裝出現的不解錯誤!完美解決方法都可以

       以下兩種方法都可以,推薦用方法一! 如果有誤,請見部落格 方法一:   步驟一: yum -y install mysql-server   步驟二:service mysqld start   步驟三:mysql -u root -p  Enter password: (預設

    第四章作業-串-計算機17級 7-1 最長對稱子串 25 分方法求解暴力列舉+動態規劃+中心擴充套件+manacher演算法馬拉車

    7-1 最長對稱子串 (25 分) 對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定Is PAT&TAP symmetric?,最長對稱子串為s PAT&TAP s,於是你應該輸出11。 輸入格式: 輸入在一行中給出長度不超過1000的非空字串

    java架構之路-設計模式建立型模式之單例模式

      設計模式自身一直不是很瞭解,但其實我們時刻都在使用這些設計模式的,java有23種設計模式和6大原則。 設計模式是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性、程式的重用性。 其中包含 建立型模式,共五種:單

    資料結構1--線性java程式碼實現線性的順序儲存

    1.資料結構的概念      資料:資訊載體,計算機處理的物件的總稱      資料元素:也稱結點,組成資料的基本單位      資料項:資料項是資料的最小單位     &n

    【尋優演算法】交叉驗證Cross Validation引數尋優的python實現:多引數尋優

    【尋優演算法】交叉驗證(Cross Validation)引數尋優的python實現:多引數尋優 一、網格搜尋原理 二、網格搜尋+交叉驗證用於多引數尋優的python實現 1、訓練模型及待尋優引數 2、直接迴圈巢狀實現網格搜尋 + cros

    【尋優演算法】交叉驗證Cross Validation引數尋優的python實現:單一引數尋優

    【尋優演算法】交叉驗證(Cross Validation)引數尋優的python實現:單一引數尋優 一、交叉驗證的意義 二、常用的交叉驗證方法 1、Hold one method 2、K-flod CV 3、Leave-One-Ou

    TensorFlow學習筆記二十三Cross Entropy交叉熵演算法實現和應用

    交叉熵(Cross-Entropy) 交叉熵是一個在ML領域經常會被提到的名詞。在這篇文章裡將對這個概念進行詳細的分析。 1.什麼是資訊量? 假設是一個離散型隨機變數,其取值集合為,概率分佈函式為 p ( x ) = r (

    Qt——QVariant隱式型別轉換實現型別系統Type System

    QVariant v(709); qDebug() << v.toInt(); QVariant w("How are you! "); qDebug()

    Java線性順序儲存——陣列實現

    第一次寫部落格,最近一直在研究資料結構,最開始準備用c語言寫資料資料結構的東西的,發現用c真的寫得我頭痛,果斷用了我喜歡的java實現,其實懂了過後用什麼語言寫都一樣的。不說了,直接上程式碼! 1.定義介面 抽象資料型別的List介面 public interface

    SpringBoot防止重複請求,重複單提交超級簡單的註解實現之四終極版

    前言:上篇文章有的童鞋說不行啊,怎麼不能防止重複提交呢! 首先需要說明的是之前的防止重複提交是指:一次請求完成之前防止重複提交,當然擴充套件下就可以做到會話間防止重複提交,還可以擴充套件為某個時間段或者永久防止重複提交(這個我就不實現了),下面我來擴充套件一下相同會話防止重

    經典演算法學習——單鏈實現氣泡排序帶頭結點

    核心程式碼如下:Node *BubbleSort(Node *pNode){ int count = SizeList(pNode);//用來控制次數 Node *pMove;

    java 手動實現單鏈尾插法和頭插法

    頭插法: 頭插法的實現相對簡單 思路是將新形成的節點的下一個賦值為header                再把新形成的節點地址傳給header即將header向前移動 import java.util.Random; import java.util.Scanner;

    java 實現陣列去重集合轉換

    public static void main(String[] args) { int[] nums = { 5, 6, 6, 6, 8, 8, 7 }; List<Integer> numList = new ArrayList<Integer

    資料結構——單鏈實現及操作c語言

    #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #d

    oracle使用decode實現豎錶轉橫 列轉行

    工作中時長會用到豎錶轉橫表(列轉行)例如某商場每天都有營業額,資料庫中營業額儲存的方式是每天很多比每筆對應不同的消費記錄 ,可能有一天的營業額很多 對應的營業額明細就會很多,如果有個需求是要統計每天營