次のステートメントを検討してください。
select interval '-1 hours'
間隔の絶対値を取得する方法、つまり、負の場合は符号を切り替えるか削除する方法がわかりませんでした。私の頭に浮かんだのは次のことだけです。
select abs(extract(epoch from interval '-1 hours'))
しかし、もっとエレガントな方法(間隔タイプを保持する方法)があるのだろうか?
次のステートメントを検討してください。
select interval '-1 hours'
間隔の絶対値を取得する方法、つまり、負の場合は符号を切り替えるか削除する方法がわかりませんでした。私の頭に浮かんだのは次のことだけです。
select abs(extract(epoch from interval '-1 hours'))
しかし、もっとエレガントな方法(間隔タイプを保持する方法)があるのだろうか?
iと-iの間に最大の値を見つけることができます。例えば:
SELECT greatest(-'1 hour'::interval, '1 hour'::interval);
pgsql-generalメーリングリストに関する議論があります:組み込み関数がPostgreSQLで提供されない理由の間隔の絶対値。
つまり、間隔タイプのコンポーネント化された性質を考慮すると、場合によっては何をすべきかについてのコンセンサスがありません。abs(interval)
しかし、誰でも、たとえばLisMorskiの答えからの式に基づいて、何を計算するかについて独自のアイデアを実装する関数を作成できます。
CREATE FUNCTION abs(interval) RETURNS interval AS
$$ select case when ($1<interval '0') then -$1 else $1 end; $$
LANGUAGE sql immutable;
単純なSQL関数は通常、クエリの実行中にインライン化されるため、パフォーマンスはクエリ内に式を含めるのと同等である必要があります。
例:
#= select abs(interval '-2 days +3 minutes');
abs
------------------
2 days -00:03:00
# select abs(now()-clock_timestamp());
abs
-----------------
00:00:00.000146
式はよりCASE
自明に見えます。例:
SELECT
i,
(CASE WHEN (i < INTERVAL '0') THEN (-i) ELSE i END) AS abs_i
FROM
(VALUES
(INTERVAL '-2 h'),
(INTERVAL '2 m')
) AS foo (i)
これは以下を生成します:
私| abs_i ----------- + ---------- -02:00:00 | 02:00:00 00:02:00 | 00:02:00
それはあなたのものよりエレガントではありませんが、それは間隔タイプを返します
select interval '-1 hours'*sign(extract(epoch from interval '-1 hours'))