2013-02-14 82 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)