標籤:
/*在實際使用sql工作中總會碰到將某一列的值放到標題中顯示.就是總說的行列轉換或者互換.比如有如下資料:ID NAME KECHENG CHENGJI-- ---------- -------------------- -------1 a 語文 80 2 a 數學 70 3 b 語文 40 4 b 數學 100 5 c 語文 90 6 c 數學 92那末我要求顯示的結果是:NAME YUWEN SHUXUE ---------- ---------------------- ----------------------a 80 70 也就是說把課程這一列放到行上顯示.把成績按照課程分配到相對應的行.我只介紹2中簡單易用的方法,使用遊標或者建立暫存資料表的方法就不介紹了.效率很慢,不易理解.首先建立表:*/create table fzq(id varchar(2),name varchar(10),kecheng varchar(20),chengji varchar(3));--插入資料:insert into fzq values (‘1‘,‘a‘,‘語文‘,‘80‘);insert into fzq values(‘2‘,‘a‘,‘shuxue‘,‘70‘);insert into fzq values (‘3‘,‘b‘,‘yuwen‘,‘40‘);insert into fzq values (‘4‘,‘b‘,‘shuxu‘,‘100‘);insert into fzq values (‘5‘,‘c‘,‘yuwen‘,‘90‘);insert into fzq values (‘6‘,‘c‘,‘shuxu‘,‘92‘);/*首先使用union.如果課程這列有多個值,那麼指令碼的代碼就很長了.*/select name,sum(yuwen) yuwen,sum(shuxue) shuxue from(select name,chengji yuwen,‘0‘ shuxue from fzqwhere kecheng=‘yuwen‘ unionselect name,‘0‘ yuwen,chengji shuxuefrom fzqwhere kecheng=‘shuxue‘) aaagroup BY name;/*執行結果:NAME YUWEN SHUXUE ---------- ---------------------- ----------------------a 80 70 b 40 100 c 90 92*//*其次是用case.這種方法代碼比較短.適合列值很多的情況.*/select name, sum(case kecheng when ‘yuwen‘ then chengji end) yuwen, sum(case kecheng when ‘shuxue‘ then chengji end) shuxuefrom fzqgroup by name;/*執行結果:NAME YUWEN SHUXUE ---------- ---------------------- ----------------------a 80 70 b 40 100 c 90 92所有例子在oracle中測試,sql server沒有測試,請根據實際情況修改如果有更好的方法,歡迎交流.*/
橫表和縱表
第一張圖就是橫表,一行表示了一個實體記錄,這就是我們傳統的設計表的形式
第二張圖就是縱表,他的一行記錄,是用於表示某個學生的屬性名稱和屬性值對應關係,像這邊有兩個屬性(名字和性別),在縱表中就要用兩條記錄來表示一個學生。
從上面可以觀察出,橫表的好處是清晰可見,一目瞭然,但是有一個弊端,如果現在要把這個表加一個欄位,那麼就必須重建表結構。對於這種情況,在縱表中只需要添加一條記錄,就可以添加一個欄位,所消耗的代價遠比橫表小,但是縱表的對於資料描述不是很清晰,而且會造成資料庫數量很多,兩者利弊在於此。所以,應該把不容易改動表結構的設計成橫表,把容易經常改動不確定的表結構設計成縱表。
在實際開發中,經常需要互相轉換橫表和縱表的形式,這裡貼個從縱表資料轉成橫表顯示的形式。
縱錶轉橫表
sql代碼:
Select student_no, max(decode(field_name,‘student_name‘,field_value)) As student_name, max(decode(field_name,‘student_sex‘,field_value )) As student_sex From cuc_student_y Group By student_no;
Oracle行列互換 橫表和縱表