2013-02-14 125 views
0

我在oracle中編寫sql查詢。我的要求是我想有條件地更新數據庫列的情況下。以下是我使用三張表格的示例數據。爲什麼這個oracle查詢說'單行子查詢返回多行'

create table z_product(uuid int, variationvalue varchar(10)); 
create table z_listprice(productid int, price int); 
create table z_variation(masterproductid int, productid int); 

insert into z_product values(1,null); 
insert into z_product values(2,null); 
insert into z_product values(3,null); 
insert into z_product values(4,null); 
insert into z_product values(5,null); 
insert into z_product values(6,null); 

insert into z_listprice values(1,10); 
insert into z_listprice values(3,20); 
insert into z_listprice values(5,10); 
insert into z_listprice values(6,19); 

insert into z_variation values(2, 1); 
insert into z_variation values(2, 3); 
insert into z_variation values(4, 5); 
insert into z_variation values(4, 6); 

我想如果所有的價值相等與「eqaul」如果價格與「notequal」消息不同的「masterproductid」更新「Variation值」列。我試圖

查詢

UPDATE z_product pr SET pr.variationvalue = 
     CASE WHEN (SELECT numberofrows FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid)) = '1' 
        AND 
        (SELECT pricecount FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid)) >1 
     THEN 'equal' 
     ELSE 'notequal' END 
WHERE pr.uuid = (SELECT prv.masterproductid 
        FROM z_variation prv, z_listprice prl 
        WHERE prv.productid = prl.productid 
        AND pr.uuid = prv.masterproductid GROUP BY prv.masterproductid) 

什麼是錯的這個查詢。我在哪裏做錯了。任何建議將大大appriciated

+0

@bernie我是新來的sql請糾正我,如果我錯了 – user964147 2013-02-14 23:45:43

+0

道歉,我的意見是口感不佳。我已經刪除它。 – bernie 2013-02-14 23:46:23

+0

錯誤消息表示您的一個或多個子查詢正在返回多個值,因此Oracle不知道要使用哪個值。 – bernie 2013-02-14 23:47:05

回答

1

多一點調查,它看起來像你返回多個PRODUCTMASTERIDs,從而返回2分的結果 - 看到這個小提琴:http://sqlfiddle.com/#!4/da309/8

結果看起來像這樣:

NUMBEROFROWS PRICECOUNT PRODUCTMASTERID 
2   1   4 
2   1   2 

這些子查詢應該只返回一行以與CASE語句一起使用。而且由於你只是檢查第一列,所以添加DISTINCT的作品。但是,如果NUMBEROFROWS是不同的值,那麼DISTINCT本身不起作用。

UPDATE z_product pr SET pr.variationvalue = 
     CASE WHEN (SELECT DISTINCT numberofrows FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid)) = '1' 
        AND 
        (SELECT DISTINCT pricecount FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid)) >1 
     THEN 'equal' 
     ELSE 'notequal' END 
WHERE pr.uuid = (SELECT prv.masterproductid 
        FROM z_variation prv, z_listprice prl 
        WHERE prv.productid = prl.productid 
        AND pr.uuid = prv.masterproductid GROUP BY prv.masterproductid) 

- 編輯 -

如果我正確理解您的需求 - 也就是,對於任何給定masterproductid,如果有的話價格在listprice表不同,那麼你要更新Variation值來notequal,但如果價格是一樣的,那麼你要UDPATE列平等,那就試試這個:

MERGE 
INTO z_product 
USING (
     SELECT COUNT(DISTINCT l.price) cnt, 
      v.masterproductid 
     FROM z_variation v 
      JOIN z_listprice l on v.productid = l.productid 
     GROUP BY v.masterproductid 
     ) 
ON  (uuid = masterproductid) 
WHEN MATCHED THEN 
UPDATE 
SET  variationvalue = CASE WHEN cnt = 1 THEN 'Equal' ELSE 'Not Equal' END 

http://sqlfiddle.com/#!4/098ad/1

希望這有助於!

+0

非常感謝您的回覆。我需要檢查所有masterproductids其變體價格是否相同,如果我必須更新產品表中的'variantvalue'列與相關的messge。如何做到這一點?謝謝 – user964147 2013-02-15 00:11:07

+0

@ user964147 - 不幸的是我必須運行大約20分鐘 - 當我返回時很樂意提供幫助。 – sgeddes 2013-02-15 00:15:02

+0

thanx很多,等待您的幫助 – user964147 2013-02-15 00:30:57

0

答:

UPDATE z_product pr SET pr.variationvalue = 
     CASE WHEN (SELECT numberofrows FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid) WHERE pr.uuid = productmasterid) = '1' 
        AND 
        (SELECT pricecount FROM (SELECT COUNT(*) AS numberofrows, pricecount , productmasterid 
           FROM (SELECT COUNT(prl.price) AS pricecount , prl.price AS price, prv.masterproductid AS productmasterid 
             FROM z_variation prv, z_listprice prl 
             WHERE prv.masterproductid = (SELECT prv.masterproductid 
                     FROM z_variation prv 
                     WHERE prv.productid = prl.productid GROUP BY prv.masterproductid) 
             AND prl.productid = prv.productid 
             GROUP BY prl.price, prv.masterproductid) 
        GROUP BY pricecount , productmasterid) WHERE pr.uuid = productmasterid) >1 
     THEN 'equal' 
     ELSE 'notequal' END 
WHERE pr.uuid = (SELECT prv.masterproductid 
        FROM z_variation prv, z_listprice prl 
        WHERE prv.productid = prl.productid 
        AND pr.uuid = prv.masterproductid GROUP BY prv.masterproductid)