OLAP是面向數據分析師的高級查詢技巧,Excel數據透視表中可以任意切換行列,也就是維度旋轉,通過sql怎麼實現是這篇文章主要內容。

關鍵詞 行轉列 列轉行 行列轉換 pivot unpivot if case when

一、OLAP和維度度量

數據庫應用分為兩種,oltp和olap,oltp聯機事務處理面向於基本日常事務和處理,比如售票,銀行交易等事務處理。Olap聯機分析處理面向決策支持,復雜的分析操作。面向決策Olap聯機分析處理需要特定的數據庫系統,和面向事務處理的數據庫系統在模式設計、索引結構,事務管理都要不同。專為決策服務的數據庫系統是面向主題、由多數據源集成、擁有當前和歷史總結數據,以讀為主的數據庫系統,也稱為數據倉庫。

數據倉庫的模式中包括事實表和維度表,事實表和維度表的關系有雪花型和星型模式。在分析應用中,維度指用戶分析的角度,比如像時間維度、區域維度、標簽維度等。度量指維度的取值。一般上維度是離散的,可以分類的,度量是連續的,是可以比較的,有的度量可以轉為維度。在很多系統中會自動區分維度和度量,一般上把數值類定義為維度,非數值類定義為度量。維度有層次,比如日期維度可以分成年、月、日、時、分秒等多層,地區可以分為國傢、省、市、區縣、鄉鎮等層次,所以有雪花型和星型區分。

多維數據分析更多內容參考:

OLAP一般包含五種操作,上卷(Roll-up):從細粒度數據向粗粒度的聚合,比如從區縣的人口統計到省市的人口,最後到全國的人口統計; 鉆取(Drill-down):上卷的相反操作,將匯總數據拆分到更細節的數據;切片(Slice):選擇維中特定的值進行分析,通過選擇某個維度的單一值進行分析,比如隻看北京的數據;切塊(Dice):選擇維中特定區間的數據或者某批特定值進行分析,和切片的不同是得到的結果維度更多;旋轉(Pivot):即維的位置的互換,類似二維表的行列轉換,可以從多個維度進行處理。本篇主要介紹其中pivot維度旋轉操作。

二、行轉列

我們假設有下面一個表,相關腳本請參考文末下載鏈接。

SELECT * FROM stuscore;

如果想要下面的結果:

第一種方案:

SELECT NAME AS '姓名',

MAX(IF(course = '語文', score, 0)) AS '語文',

MAX(IF(course = '數學', score, 0)) AS '數學',

MAX(IF(course = '英語', score, 0)) AS '英語',

MAX(IF(course = '計算機', score, 0)) AS '計算機'

FROM stuscore GROUP BY NAME;

第二種方案:

Select name as '姓名',

max(case course when '語文' then score else 0 end) as '語文',

max(case course when '數學' then score else 0 end) as '數學',

max(case course when '英語' then score else 0 end) as '英語',

max(case course when '計算機' then score else 0 end) as '計算機'

from stuscore group by name;

第三種方案可以使用子查詢,在後面子查詢中進行介紹。

上面查詢語句裡面用到瞭以下函數:

If函數:具體語法如下:

IF(expr1,expr2,expr3),如果expr1的值為真,則返回expr2的值,如果expr1的值為假,

則返回expr3的值。

if(sex=0,'女','男') 如果sex字段值為0,則返回女,否則返回男。

IF(course = '語文', score, 0) 如果course字段值是語文,則返回score的值,否則返回0.

Case when then else end函數:

case 字段 when 值 then 結果 else 其他情況 end;

case when 表達式 then 結果 else 其他情況 end;

case course when '語文' then score else 0 end course字段的值為語文時返回score,否則返回0。

Max函數:指定列取最大值。

同樣我們可以獲取每個人按照基礎學科和專業學科得分:

SELECT NAME AS '姓名',

SUM(IF(course = '語文' OR course = '數學' OR course = '英語', score, 0)) AS '基礎',

SUM(IF(course = '計算機' , score, 0)) AS '專業'

FROM stuscore GROUP BY NAME;

有的數據庫比如sqlserver或者oracle中專門有pivot和unpivot關鍵詞進行行列轉換。

三、列轉行

我們擁有下面這張表:

SELECT * FROM stuscoreline;

需要獲取所有單科成績大於60的表,包括姓名,科目和分數:需要通過列轉行操作:

select name, '語文' as 'course',chinesescore as score from stuScoreline where chinesescore>60

union all

select name, '數學' as 'course', mathscore as score from stuScoreline where mathscore>60

union all

select name, '英語' as 'course', englishscore as score from stuScoreline where englishscore>60

union all

select name, '計算機' as 'course', computerscore as score from stuScoreline where computerscore>60;

四、字典表和數據模型

數據字典,往往都是維度表。數據字典是關於數據庫中數據的描述,即元數據,而不是數據本身。數據庫中的數據都可以通過數據字典找到相關定義。

使用數據字典的好處:數據字典維護,第一便於維護管理,如果用戶需求要增加變更配置項,隻需要修改數據字典表記錄即可,不需要修改代碼。第二便於數據分析。

SELECT * FROM studentdict;

表studentdict中的sex,nation和addr都是通過字典表來實現,這樣進行修改字典表對於事實表本身沒有影響,而且進行數據分析非常方便。從數據模型來說是一個典型的星型模型,如果地址字段繼續分為國傢、省市、區縣等級別的話就是一個典型的雪花模型。

下面例子通過關聯事實表和字典表實現數據查詢:

SELECT stu.no, stu.name, age,sex.name,nation.name,addr.name FROM studentdict stu, sex,nation,addr WHERE stu.sex=sex.no AND stu.nation=nation.no AND stu.addr=addr.no;

相關數據庫腳本參考第二次腳本https://pan.baidu.com/s/1TA8kZTIfVUk_kXHT9ZTlsQ 提取碼 xa77