【问题标题】:Cursor and update in PostgresqlPostgresql 中的光标和更新
【发布时间】:2016-09-17 03:48:13
【问题描述】:

我在 postgresql 中编写了一个函数,用于使用两个游标更新表,代码执行良好,没有错误,但不执行任何操作。

我有三张桌子

  1. 产品大师
  2. 销售数据表
  3. 目标表

所以在下面的函数中,我从 1 获取产品密钥,然后在销售表中计算产品已售出的商店/网点数量,然后相应地更新第三个表,

我需要每周计算每种产品的门店数量。但它们应该是唯一的,例如如果产品在第一周在奥特莱斯 A 和 B 销售,那么第一周的商店数量应该是 2,如果它在下周在 B、C、D 销售,那么第二周的总数应该是 4周,如果它在第三周在 A 和 D 销售,那么第三周的总数应该仍然是 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;

【问题讨论】:

  • 你为什么首先使用游标,这可以通过单个更新语句更有效地完成(并且distinctNOT 一个函数)
  • 我只是选择不同的值来比较新的数字,你在哪里看到我已经将 distinct 定义为一个函数?
  • 我正在使用游标,因为我每次都要扫描整个表来计算我需要的值,我不确定单个更新将如何完成该操作
  • distinct(wk) - distinct 不是函数。这与distinct wk 相同。 distinct 始终对选择列表中的所有列进行操作。将选择列表的列放在括号中是没有用的,如果它是单列并且对于多列是完全错误的(另外:子查询中的distinct 无论如何都是无用的)
  • edit您的问题并添加相关表的定义、一些示例数据以及更新后的预期输出。我确信这可以在没有高效和缓慢的光标循环的情况下完成。

标签: sql postgresql


【解决方案1】:

您没有向我们展示您的表格是什么样子或您正​​在处理的数据到底是什么,所以我在这里做了很多假设。

使用此设置:

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);

每个产品、商店和每周的累计销售额可以这样计算:

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 表实际上并未用于此,但它可以很容易地连接到内部查询。

对于上述示例数据,返回:

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 中是唯一的。由于您在示例中混淆了表和列的名称,因此很难分辨。

【讨论】:

  • 非常感谢,它确实有效。但我仍然不确定我的光标哪里出错了......
猜你喜欢
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 2016-10-08
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多