web-dev-qa-db-ja.com

タイムスタンプ日付から1日を引く

PostgresqlにDatagripを使用しています。タイムスタンプ形式の日付フィールドを含むテーブルがあります(ex: 2016-11-01 00:00:00)。私ができるようにしたい:

  1. 数学演算子を適用して1日を減算します
  2. 今日から130日の時間枠に基づいてフィルタリングする
  3. スタンプのhh/mm/ss部分なしで表示します(2016-10-31)

現在の開始クエリ:

select org_id, count(accounts) as count, ((date_at) - 1) as dateat 
from sourcetable 
where  date_at <= now() - 130
group by org_id, dateat

1行目の((date_at)-1)句の結果:

[42883]エラー:演算子は存在しません:タイムゾーンのないタイムスタンプ-整数ヒント:指定された名前と引数タイプに一致する演算子はありません。明示的な型キャストを追加する必要がある場合があります。ポジション:69

now()句は、同様のメッセージを生成します。

[42883]エラー:演算子が存在しません:タイムゾーン付きタイムスタンプ-整数ヒント:指定された名前と引数タイプに一致する演算子はありません。明示的な型キャストを追加する必要がある場合があります。ポジション: ...

型キャストのオンラインガイドは、あまり役に立ちません。入力を歓迎します。

41
J-Ko

INTERVALタイプを使用します。例えば:

--yesterday
SELECT NOW() - INTERVAL '1 DAY';

--Unrelated to the question, but PostgreSQL also supports some shortcuts:
SELECT 'yesterday'::TIMESTAMP, 'tomorrow'::TIMESTAMP, 'allballs'::TIME;

その後、クエリで次の操作を実行できます。

SELECT 
    org_id,
    count(accounts) AS COUNT,
    ((date_at) - INTERVAL '1 DAY') AS dateat
FROM 
    sourcetable
WHERE 
    date_at <= now() - INTERVAL '130 DAYS'
GROUP BY 
    org_id,
    dateat;

追加のヒント¹

複数のオペランドを追加できます。例:今月の最終日を取得する方法は?

SELECT date_trunc('MONTH', CURRENT_DATE) + INTERVAL '1MONTH - 1DAY';

追加のヒント²

make_interval関数を使用して間隔を作成することもできます。実行時に間隔を作成する必要がある場合に便利です(リテラルを使用しません)。

SELECT make_interval(days => 10+2);
SELECT make_interval(days => 1, hours => 2);
SELECT make_interval(0, 1, 0, 5, 0, 0, 0.0);

詳細 here および here

100
Michel Milezzi