原文來自:http://blog.csdn.net/Eastmount/article/details/50559008
本文主要講述了SQL查詢語句表之間的行列轉換,同時也包括如何將一行數據轉換成兩列數據的方法、子查詢的應用、decode函數的用法。希望文章對你有所幫助~
- 1.創建數據庫表及插入數據
- 2.子查詢統計不同性質的學生總數
- 3.一行數據轉換成兩列數據 union all
- 4.表行列數據轉換(表轉置)
1.創建數據庫表及插入數據
創建數據庫、創建學生表並設置主鍵、插入數據代碼如下:
- --創建數據庫
- create database StudentMS
- --使用數據庫
- use StudentMS
- --創建學生表 (屬性:姓名、學號(pk)、學院、出生日期、性別、籍貫)
- create table xs
- (
- name varchar(10) not null,
- id varchar(10) not null,
- xy varchar(10),
- birthday datetime,
- xb char(2),
- jg varchar(8)
- )
- --創建學生表主鍵:學號
- alter table xs
- add constraint
- pk_xs primary key(id)
- --插入數據
- insert into xs
- (id, name, xb, birthday, xy, jg)
- values('1160001', '劉備', '男', '1991-11-5', '軟件學院', '河北省');
輸出數據如下圖所示:
2.子查詢統計不同性質的學生總數
使用子查詢統計不同學院總人數、不同性別總人數和河北/河南學生總人數。
- --子查詢統計人數
- select a.a_num as 軟院人數, b.b_num as 計院人數, c.c_num as 自動化人數,
- d.d_num as 男生人數, e.e_num as 女生人數, f.f_num as 河北河南人數
- from
- (select count(*) as a_num from xs where xy='軟件學院') a,
- (select count(*) as b_num from xs where xy='計算機學院') b,
- (select count(*) as c_num from xs where xy='自動化學院') c,
- (select count(*) as d_num from xs where xb='男') d,
- (select count(*) as e_num from xs where xb='女') e,
- (select count(*) as f_num from xs where jg in ('河北省','河南省')) f;
輸出結果:
PS:若中文漢字太長報錯,則需引用雙引號。如:select num as "項目(文化學術講座)"
3.一行數據轉換成兩列數據
這時,項目SQL語句的需要是顯示成兩列如下圖所示:
其實簡單編寫SQL語句,前端再處理這些數據更加方便,當然SQL也是能處理的。
當時走進了一個誤區,認為"軟件人數"是select中as自定義的一行數據的屬性,如何顯示在表中呢?當時是通過Oracle方法decode自定義顯示的,其實直接輸出,union all取代子查詢即可。當然union all其它表也可以繼續添加。
- select '軟院人數' as "統計類別", count(*) as "數量" from xs where xy='軟件學院'
- union all
- select '計院人數', count(*) from xs where xy='計算機學院'
- union all
- select '自動化人數', count(*) from xs where xy='自動化學院'
- union all
- select '男生人數', count(*) from xs where xb='男'
- union all
- select '女生人數', count(*) from xs where xb='女'
- union all
- select '河北河南人數', count(*) from xs where jg in ('河北省','河南省');
這里我簡單給大家回顧下UNION ALL方法:(參考:MIN飛翔博客)
UNION:
(1) 其目的是將兩個SQL語句的結果合並起來;
(2) 它的一個限制是兩個SQL語句所產生的欄位需要是同樣的資料種類;
(3) UNION只是將兩個結果聯結起來一起顯示,並不是聯結兩個表;
(4) UNION在進行表鏈接后會篩選掉重復的記錄。
UNION ALL:
(1) 這個指令的目的也是要將兩個 SQL 語句的結果合並在一起;
(2) UNION ALL 和 UNION 不同之處在於 UNION ALL 會將每一個符合條件的資料都列出來,無論資料值有無重復;
(3) UNION ALL只是簡單的將兩個結果合並后就返回。這樣,如果返回的兩個結果集中有重復的數據,那么返回的結果集就會包含重復的數據了。
從效率上說,sql union all的執行效率要比sql union效率要高很多,這是因為使用sql union需要進行排重,而sql union All 是不需要排重的,這一點非常重要,因為對於一些單純地使用分表來提高效率的查詢,完全可以使用sql union All。
補充:(摒棄的代碼)
當時使用decode函數,如果KWHD_WH_XZ='校級',則輸出自定義值'校級總數',否則輸出原始值;同時通過group by獲取該列所有值,sum(decode(t.KWHD_WH_XZ,'校級',1,0)計算校級的個數。
- select whxs1.num1 as 項目名稱, whxs2.num2 as 數量
- from
- (select decode(KWHD_WH_XZ, '校級', '校級總數', KWHD_WH_XZ) as num1
- from T_WSTB_KWHD_1 t
- where KWHD_WH_XZ='校級'
- group by KWHD_WH_XZ) whxs1,
- (select sum(decode(t.KWHD_WH_XZ,'校級',1,0)) as num2
- from T_WSTB_KWHD_1 t
- where KWHD_WH_XZ='校級'
- group by KWHD_WH_XZ ) whxs2;
輸出如下,但是再添加一行數據如何實現呢?所以還是推薦UNION ALL。
4.表行列數據轉換(表轉置)
參考:http://blog.163.com/dreamman_yx/blog/static/26526894201121595846270
SQL語句如下:
- select country, sum(case when type='A' then money end) as A,
- sum(case when type='B' then money end) as B,
- sum(case when type='C' then money end) as C
- from table1
- group by country
另一種方法源自文章:http://blog.sina.com.cn/s/blog_63772d910100pmln.html
方法介紹:
- decode(條件,值1,結果1,值2,結果2,值3,結果3,... 值n,結果n,缺省值)
- 函數類比:
- IF 條件=值1 THEN
- RETURN(結果1)
- ELSIF 條件=值2 THEN
- RETURN(結果2)
- ......
- ELSIF 條件=值n THEN
- RETURN(結果n)
- ELSE
- RETURN(缺省值)
- END IF
舉個例子如下:
SQL語句如下,其中sum(decode(t.result,'勝',1,0))表示result字段如果值為“勝”,則decode的結果值為1,否則取缺省值0,最后sum統計加和。
- select
- name as 姓名,sum(decode(t.result,'勝',1,0)) as 勝,sum(decode(t.result,'負',1,0)) as 負
- from t_result t
- group by name
- order by 勝 desc,負 asc
最后希望文章對你有所幫助,其實SQL語句中還是有很多非常高深的變化,目前只窺得一二啊!fighting...O(∩_∩)O
(By:Eastmount 2016-01-22 深夜5點 http://blog.csdn.net//eastmount/ )
