2016-10-31 4 views
0

200以上の国の年間値を持つ表があります。グラフィック表現のために、私は2つの特定の年の間の変化率を取得したいのですが、1990年と2013年Postgresで2行のビュー間の変化率を計算する

の表は、ビットのようになります。

id_country  year  value 
    886   2002  161.348 
    886   2003  161.348 
    886   2004  176.016 
    886   2005  176.016 
    886   2006  179.683 
    886   2007  183.35 
    886   2008  201.685 
    886   2009  227.354 
    886   2010  234.688 
    886   2011  245.689 
    886   2012  293.36 
    886   2013  440.04 
    620   1990  40.337 
    620   1991  1056.096 
    620   1992  1151.438 
    620   1993  1389.793 
    620   1994  1584.144 
    620   1995  1631.815 
    620   1996  1749.159 
    620   1997  1796.83 
    620   1998  1906.84 
    620   1999  1664.818 
    620   2000  1642.816 
    620   2001  2016.85 
    620   2002  1760.16 
    620   2003  1873.837 
    620   2004  1961.845 
    620   2005  2310.21 
    620   2006  2328.545 
    620   2007  2361.548 
    620   2008  3329.636 
    620   2009  3069.279 
    620   2010  3098.615 
    620   2011  2823.59 
    620   2012  3373.64 
    620   2013  2948.268 

私は最善の方法は、になるだろうと思いましたその差を計算するid_countryでVIEWを生成します。しかし、私はどのようにそのクエリがどのように見えるか分からない。すべての国でSELECTでなければなりません。year = 2013year = 1990で除算してください。

id_source = 1またはid_source = 2、またはid_sector = 1またはid_sector = 2のように、これらの追加の列の値によってフィルタリングすることが必要とされるであろう(追加の列によって表される)、そのテーブル内の複数の変数が存在するように、それはより複雑に得ることができます。

ご協力いただきありがとうございます。おそらく最速

答えて

1

一つの方法は、:

CREATE VIEW pct_2013_1990 AS 
SELECT id_country 
    ,  (sum(value) FILTER (WHERE year = 2013) * 100) 
    /NULLIF(sum(value) FILTER (WHERE year = 1990), 0) AS pct 
FROM tbl 
WHERE year IN (1990, 2013) 
AND id_source = 1 -- ?? 
GROUP BY id_country 
-- ORDER BY ??? 

これは、あなたが他のあなたがゼロ除算を取得し、1990年にすべての国のために値> 0を前提としています。この例ではNULLIFで防御しています。この場合、結果はNULLです。

pctは、1990年と比較した2013年の値の割合です.の割合変更をにするには、100から引きます。正確に何が必要なのか分からない。

小数点以下の桁数を減らす場合は、round()を使用します。

集計FILTER句は、Postgresの9.4で導入されました:あなたはCASE表現で置き換えることができます古いバージョンでは

代わりにセット返された関数を使用して、年を任意の年のセットで機能させるために年をパラメータ化することができます。

CREATE FUNCTION f_pct_calc(year1 integer, year2 integer) 
    RETURNS TABLE(id_country int, pct numeric) AS 
$func$ 
    SELECT t.id_country 
     ,  (sum(t.value) FILTER (WHERE year = $2) * 100) 
     /NULLIF(sum(t.value) FILTER (WHERE year = $1), 0) AS pct 
    FROM tbl t 
    WHERE t.year IN ($1, $2) 
    AND t.id_source = 1 -- ?? 
    GROUP BY t.id_country 
    -- ORDER BY ??? 
$func$ LANGUAGE sql STABLE; 

コール:

SELECT * FROM f_pct_calc(1990, 2013); 
+0

うわー、クール!本当にありがとう。小さな修正: 'FILTER'節では' FILTER(2013年) '(' country'ではなく)でなければなりません。 – luftikus143

+0

@ luftikus143:ありがとう、固定。 –