を返すPostgreSQLクエリを作成する必要があります
その日にオブジェクトが見つからなかった場合でも、結果に1日ごとにが表示されることが重要です。 (これについては前に説明しましたが、特定のケースで物事を機能させることができませんでした。)
最初に、 日の範囲を生成するSQLクエリ を見つけました。これに参加できます。
SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
AS date
FROM generate_series(0, 365, 1)
AS offs
結果:
date
------------
2013-03-28
2013-03-27
2013-03-26
2013-03-25
...
2012-03-28
(366 rows)
今、私はそれを「created」列を持つ「sharer_emailshare」という名前のテーブルに結合しようとしています:
Table 'public.sharer_emailshare'
column | type
-------------------
id | integer
created | timestamp with time zone
message | text
to | character varying(75)
ここに私が今まで持っている最高のGROUP BY
クエリがあります:
SELECT d.date, count(se.id) FROM (
select to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
AS date
FROM generate_series(0, 365, 1)
AS offs
) d
JOIN sharer_emailshare se
ON (d.date=to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))
GROUP BY d.date;
結果:
date | count
------------+-------
2013-03-27 | 11
2013-03-24 | 2
2013-02-14 | 2
(3 rows)
望ましい結果:
date | count
------------+-------
2013-03-28 | 0
2013-03-27 | 11
2013-03-26 | 0
2013-03-25 | 0
2013-03-24 | 2
2013-03-23 | 0
...
2012-03-28 | 0
(366 rows)
正しく理解している場合、これはプレーン(暗黙のINNER
)JOIN
を使用しているためであり、これは postgresのドキュメントで説明されている のように予期される動作です。
私は何十ものStackOverflowソリューションを調べてきましたが、クエリが機能するものはすべてMySQL/Oracle/MSSQLに固有のものであり、PostgreSQLに翻訳するのに苦労しています。
この質問 を求める男は、Postgresで答えを見つけましたが、しばらく前に期限切れになったPastebinリンクにそれを置きました。
LEFT OUTER JOIN
、RIGHT JOIN
、RIGHT OUTER JOIN
、CROSS JOIN
に切り替えようとしましたが、CASE
ステートメントを使用して、null、COALESCE
デフォルト値などを提供しますが、必要なものを取得する方法でそれらを使用することができませんでした。
どんな援助も大歓迎です!そして、私はすぐにその巨大なPostgreSQLの本を読み始めることを約束します;)
必要なのはleft outer join
内部結合の代わりに:
SELECT d.date, count(se.id)
FROM (SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD') AS date
FROM generate_series(0, 365, 1) AS offs
) d LEFT OUTER JOIN
sharer_emailshare se
ON d.date = to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))
GROUP BY d.date;
Gordon Linoffの有益な答えを拡張して、次のようないくつかの改善を提案します。
date_trunc('day', ...)
の代わりに::date
を使用します私のクエリは次のとおりです。
WITH dates_table AS (
SELECT created::date AS date_column FROM sharer_emailshare WHERE showroom_id=5
)
SELECT series_table.date, COUNT(dates_table.date_column), SUM(COUNT(dates_table.date_column)) OVER (ORDER BY series_table.date) FROM (
SELECT (last_date - b.offs) AS date
FROM (
SELECT GENERATE_SERIES(0, last_date - first_date, 1) AS offs, last_date from (
SELECT MAX(date_column) AS last_date, (MAX(date_column) - '1 year'::interval)::date AS first_date FROM dates_table
) AS a
) AS b
) AS series_table
LEFT OUTER JOIN dates_table
ON (series_table.date = dates_table.date_column)
GROUP BY series_table.date
ORDER BY series_table.date
クエリをテストし、同じ結果と累積合計の列を生成しました。
ゴードン・リノフの答えに基づいて、私は別の問題が元の質問で言及しなかったWHERE
句があることであることに気付きました。
裸のWHERE
の代わりに、サブクエリを作成しました。
SELECT d.date, count(se.id) FROM (
select to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD')
AS date
FROM generate_series(0, 365, 1)
AS offs
) d
LEFT OUTER JOIN (
SELECT * FROM sharer_emailshare
WHERE showroom_id=5
) se
ON (d.date=to_char(date_trunc('day', se.created), 'YYYY-MM-DD'))
GROUP BY d.date;