2016-04-04 13 views
1

postgres DB内の単一のテーブルを使用して、SQLで日付ごとに結果の行を取得しようとしています。私はユニオンを使ってみましたが、これは正しい方法ではないと思います。私は正しいSQLを構築するのに役立ちますか?postgres union結果の集約

表のコンテンツのためのサンプルデータ列:ID、のCreationDate、使用している場合

1 |2016-04-02|PAGE 
2 |2016-04-02|ATTACHMENT 
3 |2016-04-02|PAGE 
4 |2016-04-03|ATTACHMENT 
5 |2016-04-03|PAGE 
6 |2016-04-03|ATTACHMENT 
7 |2016-04-03|PAGE 
8 |2016-04-04|ATTACHMENT 
9 |2016-04-04|ATTACHMENT 
10|2016-04-04|ATTACHMENT 

をCONTENTTYPEこのSQLクエリ:

SELECT 
    date(creationdate) AS create_date, 
    COUNT(*) AS PAGE,0 AS ATTACHMENT 
FROM 
    content 
WHERE 
    contenttype='PAGE' GROUP BY content.creationdate 
UNION 
SELECT 
    date(creationdate) AS create_date, 
    0 AS PAGE,COUNT(*) AS ATTACHMENT 
FROM 
    content 
WHERE 
    contenttype='ATTACHMENT' GROUP BY content.creationdate 
ORDER BY create_date ASC; 

私は私が欲しい結果に

|create_date|PAGE|ATTACHMENT| 
|2016-04-02|0|2| 
|2016-04-02|1|0| 
|2016-04-03|0|2| 
|2016-04-03|1|0| 
|2016-04-04|3|0| 

を取得は:

|create_date|PAGE|ATTACHMENT| 
|2016-04-02|1|2| 
|2016-04-03|2|2| 
|2016-04-04|3|0| 
+2

あなたは何を期待していますか? –

+0

これらの重複を削除しますか? –

+0

私が探しているのは、日付ごとのアグリゲーションの結果です。つまり、結果に2016-04-02という2つのエントリがあるのではなく、両方の結果で1つの結果が欲しいです。 –

答えて

1

あなたは一度だけのテーブルから選択することで、条件付き集計でそれを行うことができます。

SELECT date(creationdate) AS create_date, 
     count(CASE WHEN contenttype='PAGE' then 1 end) as PAGE, 
     count(CASE WHEN contenttype='ATTACHMENT' then 1 end) as ATTACHMENT 
FROM 
    content 
GROUP BY content.creationdate 
ORDER BY create_date ASC; 
+1

には、フィルタされた集約を使用することもできます。 'count(*)filter(contenttype = 'PAGE')' –

+0

はい( 'false'は' 0'とは異なるものを除いて、これはMySQLではありません)http://www.postgresql.org/docs/current/静的/ sql-expressions.html#構文集約 –

+0

@dnoethがsumで行ったようにelseを送ることができない以外は、countの利点を実際に見ることはできません。ケースの価値/は本当に無関係です。 –

1

あなたは条件付き集計が必要になります。

SELECT 
    date(creationdate) AS create_date, 
    SUM(CASE WHEN contenttype='PAGE' THEN 1 ELSE 0 END) AS PAGE, 
    SUM(CASE WHEN contenttype='ATTACHMENT' THEN 1 ELSE 0 END) AS ATTACHMENT 
FROM 
    content 
GROUP BY content.creationdate 
ORDER BY create_date ASC; 
+0

サンプルデータにPAGEおよびATTACHMENT以外の値が含まれている場合は、もう1つは空のエントリを再度取得します。これを避ける方法はありますか? –

+1

@ WillemP.Botha: 'PAGE'と' ATTACHMENT'の両方がゼロである*空のエントリ*はどういう意味ですか?集計の前に他の値を削除するために 'WHERE'条件を追加するか、別の' SUM(CASE ...) 'を追加することができます。 – dnoeth

+0

すべての値に対してSUM(CASE)を追加しましたが、単純化するためにWHERE CLAUSEを行ったと思います。現在のPostgresバージョンの –

0

、いくつかの方法:

SELECT date(c.creationdate) AS create_date, 
p p_count,a_count 
FROM 
(SELECT DISTINCT creationdate FROM content) c INNER JOIN (SELECT creationdate,count() p_count FROM CONTENT GROUP 
BY creationdate,contenttype HAVING contenttype='PAGE') p on p.creationdate=c.creationdate 
INNER JOIN (SELECT creationdate,count() a_count FROM CONTENT GROUP 
BY creationdate,contenttype HAVING contenttype='ATTACHMENT') p 
ON p.creationdate=c.creationdate ORDER BY c.creationdate 

これはこれです

+0

ここで何をやったのですか? – sagi

+0

別の方法...最も一般的な – jurhas

+2

このSQLは本当に私の頭を傷つける –

関連する問題