2016-09-16 18 views
0

私は2つのカーソルを使ってテーブルを更新する関数をpostgresqlに書いています。コードはエラーなく正常に実行されますが、何もしません。PostgreSQLのカーソルと更新

私が1からプロダクトキーを取得してからでてる、以下の機能にそう3つのテーブル

  1. 商品マスタ
  2. 売上データテーブル
  3. ターゲット表

を持っています製品が販売された店舗/店舗の数を計算した後、それに応じて第3のテーブルを更新する販売テーブル

毎週各製品のアウトレットの数を計算する必要があります。しかし、それらはユニークでなければなりません。例えば、製品が最初の週に店舗AとBで販売された場合、最初の週の店舗数は2でなければならず、B、C、Dで販売された場合は、 3週目にAとDで販売されている場合は、3週間目の合計は4です。どうすればいいの?

ご協力いただきますようお願い申し上げます。

create or replace function StCount() returns void as 
    $BODY$ 
    Declare 
     ik1 integer ; 
    wk1 integer ; 
    Cur1 CURSOR FOR SELECT ik From table1 ; 
     Cur2 CURSOR FOR SELECT distinct(wk) FROM table2 order by wk asc; 


    begin 
    OPEN Cur1 ; 
    WHILE (Found) Loop 
    FETCH next from Cur1 INTO ik1 ; 

OPEN Cur2 ; 

    WHILE (Found) Loop 
    FETCH next from Cur2 INTO wk1;  

       update table3 set skly =(select count(sk)from table2 a 
     where a.ik = ik1 and a.wk = wk1 
     and a.sk not in (select distinct (sk) from table2 
     where ik = ik1 and wk <= wk1 - 1)) 
     where ik = ik1 and wk = w1 
     ; 


    End loop ; 
CLOSE Cur2; 

    end loop ; 

    CLOSE Cur1; 

    END; 
    $BODY$ 
    LANGUAGE plpgsql VOLATILE; 
+2

なぜ最初にカーソルを使用しているのですか?これは、単一の更新ステートメントではるかに効率的に行うことができます( 'distinct'は*** NOT ***関数です) –

+0

私は、別のものを関数として定義したのはどこですか? – puzeledbysql

+0

私は、テーブル全体をスキャンして必要な値をカウントするたびにカーソルを使用しているので、単一の更新でどのように達成されるのかよく分かりません – puzeledbysql

答えて

0

あなたは、テーブルがどのように見えるかを正確にどのようなデータは、あなたが扱っているので、私はここに多くのことを想定していますどのように私たちを示しませんでした。

create table product (id integer primary key); 
create table sales (id serial primary key, product_id integer, store text, wk integer); 

insert into product values (1),(2),(3),(4); 

insert into sales (product_id, store, wk) 
values 
    (1, 'A', 1), 
    (1, 'B', 1), 
    (1, 'B', 2), 
    (1, 'C', 2), 
    (1, 'D', 2), 
    (1, 'A', 3), 
    (1, 'D', 3); 

製品、店舗や週累計販売台数

は次のように計算することができます:

この設定を使用して

productテーブルは実際にはこの中で使用されていない。なお
select product_id, 
     store, 
     wk, 
     count(store) over (partition by product_id order by wk) as sofar 
from (
    select product_id, 
     store, 
     wk, 
     row_number() over (partition by product_id, store order by wk) as rn 
    from sales 
    order by product_id, store 
) t 
where rn = 1; 

、内部クエリーに簡単に結合することができます。上記のサンプルデータについて

、これは戻します

product_id | store | wk | sofar 
-----------+-------+----+------ 
     1 | A  | 1 |  2 
     1 | B  | 1 |  2 
     1 | C  | 2 |  4 
     1 | D  | 2 |  4 

は今、この結果は、ターゲットテーブルを更新するために使用することができる。

update target_table 
    set slky = t.sofar 
from (
    select product_id, 
      store, 
      wk, 
      count(store) over (partition by product_id order by wk) as sofar 
    from (
     select product_id, 
      store, 
      wk, 
      row_number() over (partition by product_id, store order by wk) as rn 
     from sales 
     order by product_id, store 
    ) t 
    where rn = 1 
) s 
where s.wk = target_table.wk 
    and s.product_id = target_table.product_id 
    and s.store = target_table.store; 

これは、(product_id, store, wk)の組み合わせがtarget_tableで一意であることを前提としてい。あなたの例であなたのテーブルと列の名前を難読化しているので、それを理解するのは難しいです。

+0

ありがとう、それはうまくいった。しかし、私はカーソルがどこに間違っていたのかまだ分かりません... – puzeledbysql

関連する問題