[Postgres]合並多行到一列(轉)


轉自http://csk83.sinaapp.com/?p=104

在實際應用中常常遇見這樣的情況,見下表,我們現在需要統計出來每年每個人的工資總和以及發放月份。

user_name year month money
張三 2011 1 900
張三 2011 2 1200
張三 2011 5 1100
張三 2011 6 1300
李四 2011 1 1100
李四 2011 3 1200

即我們要得到下面表的結果

user_name year monthes total money
張三 2011 1,2,5,6 4500
李四 2011 1,3 2300

首先我們想到的是有這樣的SQL語句:
SELECT user_name,year,myfunction(month) AS monthes, SUM(money) AS total_money FROM table GROUP BY user_name,year;

像count或者sum一樣吧數據表中的某個字段按照需要拼接起來,但是在PostgreSQL好像沒有直接的方法來實現(或許有筆者沒有發現,正因為沒有發現所以筆者才研究了半天得到下面的心得)。

方法一:在PostgreSQL中如果不自定義函數直接用SQL來實現

SELECT t1.user_name, t1.year, ARRAY_TO_STRING(array(SELECT t2.month FROM table t2 WHERE t2.user_name=t1.user_name AND  t2.year=t1.year), ‘,’)  AS monthes, SUM(t1.money) AS total_money FROM table t1 WHERE 1 GROUP BY t1.user_name, t1.year;

這里主要是用了PostgreSQL的內置數組函數array_to_string把數組拼接成字符串。

方法二:自己寫一個聚合函數csk_test來實現

結合上面array_to_sting的用法,根據聚合函數定義方法研究出用聚合函數來實現的方法:

– 1 開啟plpgsql的支持,如果沒有需要運行下面兩行SQL開啟plpgsql支持
CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS ‘$libdir/plpgsql’ LANGUAGE C;
CREATE TRUSTED LANGUAGE plpgsql HANDLER “plpgsql_call_handler”;
– 2 創建函數
—- 2.1 收集數據到一個數組
CREATE FUNCTION csk_test_start(a TEXT[], s TEXT) RETURNS TEXT[] AS $$
BEGIN
RETURN a || s;
END;
$$ LANGUAGE plpgsql;
—- 2.2 最后處理函數,把數組轉換成字符串輸出
CREATE FUNCTION csk_test_final(a TEXT[]) RETURNS TEXT AS $$
BEGIN
RETURN array_to_string(a, ‘,’);
END;
$$ LANGUAGE plpgsql;
– 3 創建聚集函數
CREATE AGGREGATE csk_test(
BASETYPE = TEXT,
SFUNC = csk_test_start,
STYPE = TEXT[],
FINALFUNC = csk_test_final
);

現在我們再次用本文開始的SQL就可以實現我們的要求了
SELECT user_name,year,csk_test(CAST(month to varchar)) AS monthes, SUM(money) AS total_money FROM table GROUP BY user_name,year;

需要注意的是,上面的聚集函數接收的數據類型是text,所以在用的時候month整型轉換成了varchar類型,當然也可以直接修改上面的代碼讓它們的類型一致。聚合函數在文本字段的處理上在PostgreSQL 8.4上測試通過了,至於數字類型其他類型轉換后是否能行沒有測試過。

方法二是通過聚合函數引用自定義函數來實現的,其實還可以直接調用系統函數array_append來實現:

CREATE AGGREGATE csk_test(
basetype = integer,
sfunc = array_append,
stype = integer[],
initcond = ‘{}’
);

 

可參考http://www.postgresql.org/docs/9.1/static/functions-array.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM