建立測試用表:函數
create table test1
(s_name varchar(10),
s_class varchar(10),
c_value numeric
);測試
插入測試數據:.net
insert into test1 values('張三','語文',78),('張三','數學',38),('張三','英語',89),('張三','化學',86),('張三','物理',68);
insert into test1 values('李四','語文',58),('李四','數學',67),('李四','英語',82),('李四','化學',56),('李四','物理',39);排序
通常查詢及結果:get
select s_name,s_class,c_value from test1;數學
行轉列查詢及結果:it
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2') table
as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric)
class
心得:test
1,行轉列每個字段必須爲text類型,若是表結構不是text就須要進行轉換。
2,爲了能方便閱讀要給轉換後的列寫一個別名,這時須要注意的是,若是不排序查詢結果是隨機的,如上寫成:
select * from crosstab('select s_name::text,s_class,c_value from test1')
as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric);
因此別名要按排序的結果寫
3,分類個數宜多不宜少,少了數據丟失
少:
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2')
as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric);
顯然這個丟失了」語文「,結果問題還不大,至少數據是正確的
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2')
as ct (姓名 text,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric);
這樣結果徹底是錯誤的
多:
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2')
as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric,歷史 numeric);
對結果沒有什麼影響
如今,多加一條記錄:
insert into test1 values('王五','語文',58),('王五','英語',82),('王五','化學',56),('王五','物理',39);
再查詢:
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2') as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric,歷史 numeric);
第三行出問題了
那麼能夠這麼解決:
select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2','select distinct s_class from test1 order by 1')
as ct (姓名 text,"化學" numeric,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric);
顯然這樣比較準確,可是不是crosstab(text)輸入一個參數的方法就沒有必要了呢?
固然不,至少他的列數是能夠隨意變都沒有報錯,只要注意列的順序且排前的列沒有空值,仍是有用處的。
crosstab這個用起來準確得多,固然限制也多一些,轉換的列數必須與distinct個數同樣,多或少都會報錯。
總之,這函數用起來雷仍是挺多的,要是能整合一下就更完美了。