行轉列crosstab使用心得

建立測試用表:函數

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;數學

image

行轉列查詢及結果: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

image

心得: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);

image
顯然是不對的。

因此別名要按排序的結果寫

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);

image

顯然這個丟失了」語文「,結果問題還不大,至少數據是正確的

select * from crosstab('select s_name::text,s_class,c_value from test1 order by 1,2')

as ct (姓名 text,"數學" numeric,"物理" numeric,"英語" numeric,"語文" numeric);

image

這樣結果徹底是錯誤的

 

多:

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);

image

對結果沒有什麼影響

如今,多加一條記錄:

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);

image

第三行出問題了

那麼能夠這麼解決:

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);

image

顯然這樣比較準確,可是不是crosstab(text)輸入一個參數的方法就沒有必要了呢?

固然不,至少他的列數是能夠隨意變都沒有報錯,只要注意列的順序且排前的列沒有空值,仍是有用處的。

crosstab這個用起來準確得多,固然限制也多一些,轉換的列數必須與distinct個數同樣,多或少都會報錯。

總之,這函數用起來雷仍是挺多的,要是能整合一下就更完美了。

相關文章
相關標籤/搜索