sql >> データベース >  >> RDS >> PostgreSQL

タイムゾーンなしで日付とタイムスタンプを比較する関数をplpgsqlで作成するにはどうすればよいですか?

    Pavelが言ったこと

    さらに、PL/pgSQLが最初から必要であることを示すものは何もありません。プレーンな(準備された)SELECT ステートメントはそれを行うことができます。または、データベースに永続化する場合はSQL関数。参照:

    そして懸念:

    包括的/排他的上限/下限を正確に定義する 意外なコーナーケースの結果を避けるため。 timestampを比較する場合 列からdate 、後者は、その日の最初のインスタンスを示すタイムスタンプに強制変換されます:YYYY.MM.DD 00:00:00

    あなたの質問は言う:

    measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate
    

    ...これにはfirstDateのすべてが含まれます 、ただし、 lastDateをすべて除外します 00:00の最初の(共通の)インスタンスを除く 。通常、あなたが望むものではありません。あなたの定式化を考えると、これがあなたが本当に望んでいるものだと思います:

    CREATE OR REPLACE FUNCTION get_measurements_by_node_and_date(node_id integer
                                                               , firstDate date
                                                               , lastDate date) 
      RETURNS TABLE (measurement_id integer
                   , node_id integer
                   , carbon_dioxide float8
                   , hydrocarbons float8
                   , temperature float8
                   , humidity float8
                   , air_pressure float8
                   , measurement_timestamp timestamp)
      LANGUAGE sql STABLE AS
    $func$
       SELECT m.id
            , m.node_id
            , m.carbon_dioxide
            , m.hydrocarbons
            , m.temperature
            , m.humidity
            , m.air_pressure
            , m.measurement_timestamp -- AS measure  -- just documentation
       FROM   public.measurements_lora m
       WHERE  m.node_id = _node_id
       AND    m.measurement_timestamp >= firstDate::timestamp
       AND    m.measurement_timestamp < (lastDate + 1)::timestamp  -- ①!
    $func$;
    

    ①これにはlastDateのすべてが含まれます 、そして効率的に。 integer dateとの間の値 日を加算/減算するには::timestampへの明示的なキャスト 式で日付が自動的に強制変換されるため、はオプションです。しかし、ここで混乱を解消しようとしているので...

    関連:

    余談1:

    いいえ。timestamp 値はではありません フォーマットされた期間。これらは単なるタイムスタンプ値です(エポックからのマイクロ秒数として内部的に保存されます)。表示は値とは完全に分離されており、を変更せずに101通りの方法で調整できます。 。何が起こっているのかをよりよく理解するために、この誤解を取り除きます。参照:

    余談2:

    SQLの悪意のある性質についてBETWEEN

    余談3:

    Postgresの正当な小文字の識別子を検討してください。 first_date firstDateの代わりに 。参照:

    関連:



    1. 挿入更新トリガー挿入または更新かどうかを判断する方法

    2. JSONBオブジェクトから真の値を持つキー名を抽出する

    3. MySQLクエリエラー-自動コイン追加

    4. PL / pgSQL関数から複数の行を返す方法は?