2016-11-24 9 views
2

私は以前の(遅れ)計算値を取得したいですか?PostgreSQL - 前回(遅れ)の計算値を得るには

id | value 
-------|------- 
    1 | 1 
    2 | 3 
    3 | 5 
    4 | 7 
    5 | 9 

私は何を達成しようとしています。これです:

id | value | new value 
-------|-------|----------- 
    1 | 1 | 10  <-- 1 * lag(new_value) 
    2 | 3 | 30  <-- 3 * lag(new_value) 
    3 | 5 | 150  <-- 5 * lag(new_value) 
    4 | 7 | 1050  <-- 7 * lag(new_value) 
    5 | 9 | 9450  <-- 9 * lag(new_value) 

私が試してみました:

SELECT value, 
     COALESCE(lag(new_value) OVER() * value, 10) AS new_value 
FROM table 

エラー:

ERROR: column "new_value" does not exist

+0

が見えますか? –

+0

@JuanCarlosOropezaはいメイトです。私はここで何を使うべきですか?再帰CTEまたはラテラル結合? – Willem

+3

再帰CTE。簡単にする必要があります。より多くのヘルプが必要な場合は教えてください。https://www.postgresql.org/docs/9.4/static/queries-with.html –

答えて

1
ファンの答えに似

が、私はとにかくそれを投稿しようと思いました。それは、少なくともID列の必要性を回避し、最後に空の行を持っていません。

with recursive all_data as (
    select value, value * 10 as new_value 
    from data 
    where value = 1 

    union all 

    select c.value, 
     c.value * p.new_value 
    from data c 
    join all_data p on p.value < c.value 
    where c.value = (select min(d.value) 
        from data d 
        where d.value > p.value) 
) 
select * 
from all_data 
order by value; 

アイデアは、1つの「親」の行に再帰部分では正確に一つの行に参加することです。 「正確に1つの親」は導出されたテーブルと横方向の結合で実行できますが(驚くほどになります)、limitを許可します。再帰的な部分の「子」からの「ちょうど1つの行」は残念なことにサブセレクトをmin()でのみ行うことができます。

同様に再帰部分にorder bylimitを使用することが可能であったが、残念ながらそれは現在のPostgresのバージョンでサポートされていない場合where c.value= (...)は必要ではないであろう。

オンライン例:再帰的な計算、イマイチであるようhttp://rextester.com/WFBVM53545

+0

ニース。私はあなたの例をあげよう。私はまだフアンを働かせようとしています。私が仕事に就いたのは限界と相殺でした。各ステートメントは角括弧内に囲みます。 '(SELECT ..... LIMIT 1)UNION ALL(SELECT .... OFFSET 1)'です。 – Willem

+0

私はデータがランダムであることを説明するOPとして「MIN(value)」で基本ケースを変更します。 –

+0

はい、その 'order by-limit'制限は、私の人生をミスラブルにしています:( –

1

を私の悪い、このありえません私は思ったように簡単です。非常に近い結果が得られましたが、まだチューニングが必要です。

DEMO

WITH RECURSIVE t(n, v) AS (
    SELECT MIN(value), 10 
    FROM Table1 

    UNION ALL 
    SELECT (SELECT min(value) from Table1 WHERE value > n), 
      (SELECT min(value) from Table1 WHERE value > n) * v 
    FROM t 
    JOIN Table1 on t.n = Table1.value  
)  
SELECT n, v 
FROM t; 

OUTPUT

+0

少なくともあなたは結果を得ました。 +1 – Willem

+0

あなたのテーブルにIDを追加する方が簡単です;) –

+0

私はIDを持っています。だからあなたはそれをidの仕事に変えることができます。私は質問を更新します – Willem