PostgreSQL 實現交叉表(行列轉換)的五種方法
原始表資料如下:
- t_girl=# select * from score;
- name | subject | score
- -------+---------+-------
- Lucy | English | 100
- Lucy | Physics | 90
- Lucy | Math | 85
- Lily | English | 95
- Lily | Physics | 81
-
Lily | Math | 84
- David | English | 100
- David | Physics | 86
- David | Math | 89
- Simon | English | 90
- Simon | Physics | 76
- Simon | Math | 79
- (12 rows)
- Time: 2.066 ms
想要實現以下的結果:
- name | English | Physics | Math
- ------+---------+---------+------
-
Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
大致有以下幾種方法:
1、用標準SQL展現出來
- t_girl=# selectname,
- t_girl-# sum(casewhen subject = 'English'then score else 0 end) as"English",
-
t_girl-# sum(casewhen subject = 'Physics'then score else 0 end) as"Physics"
- t_girl-# sum(casewhen subject = 'Math'then score else 0 end) as"Math"
- t_girl-# from score
- t_girl-# groupbynameorderbynamedesc;
- name | English | Physics | Math
- -------+---------+---------+------
- Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
- (4 rows)
- Time: 1.123 ms
2、用PostgreSQL 提供的第三方擴充套件 tablefunc 帶來的函式實現
以下函式crosstab 裡面的SQL必須有三個欄位,name, 分類以及分類值來作為起始引數,必須以name,分類值作為輸出引數。
- t_girl=# SELECT *
- FROM crosstab('select name,subject,score from score order by name desc',$$values ('English'::text),('Physics'::text),('Math'::text)$$)
- AS score(name text, English int, Physics int, Math int);
- name | english | physics | math
- -------+---------+---------+------
- Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
- (4 rows)
- Time: 2.059 ms
3、用PostgreSQL 自身的聚合函式實現
- t_girl=# selectname,split_part(split_part(tmp,',',1),':',2) as"English",
- t_girl-# split_part(split_part(tmp,',',2),':',2) as"Physics",
- t_girl-# split_part(split_part(tmp,',',3),':',2) as"Math"
- t_girl-# from
- t_girl-# (
- t_girl(# selectname,string_agg(subject||':'||score,',') as tmp from score groupbynameorderbynamedesc
- t_girl(# ) as T;
- name | English | Physics | Math
- -------+---------+---------+------
- Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
- (4 rows)
- Time: 2.396 ms
4、 儲存函式實現
- createorreplacefunction func_ytt_crosstab_py ()
- returns setof ytt_crosstab
- as
- $ytt$
- for row in plpy.cursor("select name,string_agg(subject||':'||score,',') as tmp from score group by name order by name desc"):
- a = row['tmp'].split(',')
- yield (row['name'],a[0].split(':')[1],a[1].split(':')[1],a[2].split(':')[1])
- $ytt$ language plpythonu;
- t_girl=# selectname,english,physics,math from func_ytt_crosstab_py();
- name | english | physics | math
- -------+---------+---------+------
- Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
- (4 rows)
- Time: 2.687 ms
5、 用PLPGSQL來實現
- t_girl=# create type ytt_crosstab as (name text, English text, Physics text, Math text);
- CREATE TYPE
- Time: 22.518 ms
- createorreplacefunction func_ytt_crosstab ()
- returns setof ytt_crosstab
- as
- $ytt$
- declare v_name text := '';
- v_english text := '';
- v_physics text := '';
- v_math text := '';
- v_tmp_result text := '';
- declare cs1 cursorforselectname,string_agg(subject||':'||score,',') from score groupbynameorderbynamedesc;
- begin
- open cs1;
- loop
- fetch cs1 into v_name,v_tmp_result;
- exit whennot found;
- v_english = split_part(split_part(v_tmp_result,',',1),':',2);
- v_physics = split_part(split_part(v_tmp_result,',',2),':',2);
- v_math = split_part(split_part(v_tmp_result,',',3),':',2);
- return query select v_name,v_english,v_physics,v_math;
- end loop;
- end;
- $ytt$ language plpgsql;
- t_girl=# selectname,English,Physics,Math from func_ytt_crosstab();
- name | english | physics | math
- -------+---------+---------+------
- Simon | 90 | 76 | 79
- Lucy | 100 | 90 | 85
- Lily | 95 | 81 | 84
- David | 100 | 86 | 89
- (4 rows)
-
相關推薦
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實現豎錶轉橫表 (列轉行)
工作中時長會用到豎錶轉橫表(列轉行)例如某商場每天都有營業額,資料庫中營業額儲存的方式是每天很多比每筆對應不同的消費記錄 ,可能有一天的營業額很多 對應的營業額明細就會很多,如果有個需求是要統計每天營