2017-06-30 5 views
1

投稿者:Postgresの天才、私は助けが必要です。私は大量のデータをグラフ化しようとしており、フロントエンドに送信する前にデータベース内でできる限りデータを準備したいと考えています。Postgresは要素を数え、日付で列化します。

Source | Date 
--------|------------ 
Email | 2017-06-01 
Email | 2017-06-01 
Email | 2017-06-03 
Email | 2017-06-03 
Email | 2017-06-03 
Email | 2017-06-04 
Email | 2017-06-06 
Email | 2017-06-06 
Email | 2017-06-07 
Banner | 2017-06-01 
Banner | 2017-06-02 
Banner | 2017-06-03 
.... 

そして、私はそれをすべて、その後columnized日によってカウントを取得する必要があると日付のためのゼロの結果があれば、私はzerofilled必要があります。私は、このような結果のセットを持っているのPostgres 9.6

を使用しています。

望ましい結果:

Source | 2017-06-01 | 2017-06-02 | 2017-06-03 | ... | 2017-06-07 
--------|-------------|-------------|-------------|------|------------ 
Email | 2   | 0   | 3   | ... | 1 
Banner | 1   | 1   | ...   

私はあなたに感謝、これは理にかなって願っています。

+0

あなたはどのように多くの日付の列が必要なのですか?それは固定ですか? –

+0

列は固定されていません。おそらくすべての値のjsonである単一の列を返すこともできますが、その日付のレコードがない場合はゼロ値を持つ必要があります。 –

答えて

0

することができます使用次のいずれか

SELECT 
    * 
FROM 
    crosstab(
    $$ 
     SELECT "Source", "Date"::text, count("Date") 
     FROM t 
     GROUP BY "Source", "Date" 
     ORDER BY "Source" 
    $$, 
    $$ 
     SELECT cast(d as date) 
     FROM generate_series(date '2017-06-01', date '2017-06-10', interval '1 day') as s(d) 
    $$ 
    ) AS 
    (
     "Source" text, 
     "2017-06-01" bigint, 
     "2017-06-02" bigint, 
     "2017-06-03" bigint, 
     "2017-06-04" bigint, 
     "2017-06-05" bigint, 
     "2017-06-06" bigint, 
     "2017-06-07" bigint, 
     "2017-06-08" bigint, 
     "2017-06-09" bigint, 
     "2017-06-10" bigint 
    ) ; 

のPostgreSQL固有のcrosstab(text source_sql, text category_sql)を使用し、それがtablefunc拡張を必要とするか、 "古典SQLのピボット" 行くことができます:

SELECT 
    "Source" 
    ,COUNT(CASE WHEN "Date" = '2017-06-01' THEN 1 END) AS "2017-06-01" 
    ,COUNT(CASE WHEN "Date" = '2017-06-02' THEN 1 END) AS "2017-06-02" 
    ,COUNT(CASE WHEN "Date" = '2017-06-03' THEN 1 END) AS "2017-06-03" 
    ,COUNT(CASE WHEN "Date" = '2017-06-04' THEN 1 END) AS "2017-06-04" 
    ,COUNT(CASE WHEN "Date" = '2017-06-05' THEN 1 END) AS "2017-06-05" 
    ,COUNT(CASE WHEN "Date" = '2017-06-06' THEN 1 END) AS "2017-06-06" 
    ,COUNT(CASE WHEN "Date" = '2017-06-07' THEN 1 END) AS "2017-06-07" 
    ,COUNT(CASE WHEN "Date" = '2017-06-08' THEN 1 END) AS "2017-06-08" 
    ,COUNT(CASE WHEN "Date" = '2017-06-09' THEN 1 END) AS "2017-06-09" 
    ,COUNT(CASE WHEN "Date" = '2017-06-10' THEN 1 END) AS "2017-06-10" 
FROM 
    t 
GROUP BY 
    "Source" 
ORDER BY 
    "Source" ; 
 
Source | 2017-06-01 | 2017-06-02 | 2017-06-03 | 2017-06-04 | 2017-06-05 | 2017-06-06 | 2017-06-07 | 2017-06-08 | 2017-06-09 | 2017-06-10 
:----- | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: | ---------: 
Banner |   1 |   1 |   1 |   0 |   0 |   0 |   0 |   0 |   0 |   0 
Email |   2 |   0 |   3 |   1 |   0 |   2 |   1 |   0 |   0 |   0 

どちらも同じ値を返します。違いは2番目に「0」、最初にはカウントする値がない場合は「null」を返します。

dbfiddle here

+0

質問をフォローアップすると、select文を作成して日付範囲が動的になるようにする方法がありますか?私が開始日と終了日を渡し、動的に列を構築する関数を作成するとしますか? –

+1

これは、動的SQLとともに関数で行うことができます。 https://www.postgresql.org/docs/current/static/ecpg-dynamic.htmlを確認してください – joanolo

+0

うわーは私の頭の上に少し(または多く)を得ています。おそらくあなたがそれに似ているかもしれないリンクすることができる例がありますか?私はグーグルのポストグルとダイナミックSQLを試し、さまざまな接線のトンを得た。感謝しなければ、これはすでに非常に役立っています。 –

関連する問題