2013-10-04 56 views
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;  

產品表有兩個條目 - pseudo(flag ='Y')和actual(flag ='N')。加入內部查詢中的子句排序

如果沒有僞產品,需要取實際的產品。

上述查詢導致編譯錯誤。 內部查詢可能會返回多個記錄,但我只需要第一個記錄(即'Y'記錄。如果找不到'Y'rec,則需要'N'rec)。

+0

@YasinOkumus:內部查詢可能會返回兩條記錄。如果存在,我需要'Y'記錄,否則需要'N'記錄。 – HanuAthena

+0

我有點遲到了,所以我刪除了我的評論對不起。我正在寫一個答案,我希望我這次得到了正確的答案,並且你可以得到解決方案。 :) –

+0

是「和rownum = 1」試圖獲得只有一個記錄? –

回答

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 
+0

閱讀http://www.oracle-base.com/articles/misc/top-n-queries.php後,您可能需要將關鍵字「distinct」添加到該查詢中。條件「rn = 1」的 –

+0

除非他的數據需要,否則不需要區分。但我不知道他在桌上有什麼。 – Farid

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 
+0

我試過這個,但是它不能識別內部查詢中的「我」。 – HanuAthena

+0

我現在不能嘗試,但它很奇怪。也許你應該考慮改變更新查詢,因爲它是通過這兩個表(產品和產品)的innter連接寫成的:http://geekswithblogs.net/WillSmith/archive/2008/06/18/oracle-update-with-加入-again.aspx –

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; 

就像我上面說的,我自由處理這個,所以仔細檢查語法。