0
create table items(item_pk integer, pgid integer, prod_id integer, PRIMARY KEY(item_pk));
create table products(prod_id integer, version  integer, pgid  integer, flag char(1), PRIMARY KEY(prod_id));

insert into items(item_pk,  pgid) values (1,  21);
insert into items(item_pk, pgid) values(2,  31);
insert into products(prod_id, version, pgid, flag) values (11, 101,  21, 'Y');
insert into products(prod_id, version, pgid, flag) values (22, 101,  21, 'N');
insert into products(prod_id, version, pgid, flag) values(33, 101, 31, 'N');

   declare 
    prod_version NUMBER := :1 ;  
    begin  
    update items i set i.prod_id = ( 
     select p.prod_id from products p where 
     p.version = prod_version and p.pgid = i.pgid and rownum =1 
     order by p.flag desc
    ) where i.xyz is null
    commit; end;    

产品表有两个条目 - 伪(标志 = 'Y')和实际(标志 = 'N')。

如果没有伪产品,则需要获取实际产品。

上述查询导致编译错误。内部查询可能返回多个记录,但我只需要第一个(即“Y”记录。如果找不到“Y”记录,则需要“N”记录)。

4

3 回答 3

0

有点矫枉过正,但应该工作:

select prod_id
from (
    select p.prod_id, ROW_NUMBER() OVER (ORDER BY p.flag DESC) as rn
    from products p
    where p.version = prod_version and p.pgid = i.pgid
    )
where rn=1
于 2013-10-04T18:15:44.153 回答
0

您需要在更新查询中进行另一个选择。我想它需要是这样的;

update items i set i.prod_id = ( 
  select prod.id from (
    select p.prod_id,rownum rn from products p where 
    p.version = prod_version and p.pgid = i.pgid
  order by p.flag desc) x 
    where x.rn=1
) where i.xyz is null
于 2013-10-04T18:16:00.670 回答
0

我没有任何可用的 ide 来检查我的语法。我正在从文本编辑器中执行此操作,因此可能存在错误。

我总是尽量避免在查询中使用任何类型的 rownum,因此这可以使用子查询来获取“N”值。

declare 
   prod_version NUMBER := :1 ;  
begin  
  update items i set i.prod_id = (select p.prod_id
                                    from products p
                                   where p.version = prod_version
                                     and p.pgid = i.pgid
                                     and (p.flag = 'Y' 
                                          or (p.flag = 'N' and 0 = (select count(*)
                                                                  from products p2
                                                                 where p2.version = prod_version
                                                                   and p2.pgid = i.pgid
                                                                   and p2.flag = 'Y')
                                              )
                                          )
                                 )
  where i.xyz is null
  commit;
end;

但是,您始终可以使用 plsql 并执行类似的操作。

declare
  temp_prod_id number;
  prod_version NUMBER := :1 ; 

begin
  for v_rec in (select id, pgid from items where xyz is null) loop
    begin
      select prod_id into temp_prod_id from products p
       where p.version = prod_version
         and p.pgid = v_rec.pgid
         and p.flag = 'Y';
    exception
    when no_data_found then
      select prod_id into temp_prod_id from products p
       where p.version = prod_version
         and p.pgid = v_rec.pgid
         and p.flag = 'N';
  -- this assumes there's always an 'N' record if not wrap this select with exception handling.
    end;

    update items i set i.prod_id = temp_prod_id
    where items.id = v_rec.id;
    commit;
  end loop;
end;

就像我上面说的,我可以随意处理这个,所以仔细检查语法。

于 2013-10-04T18:49:59.117 回答