需要Oracle Update声明澄清

时间:2016-09-18 23:35:39

标签: sql oracle rdbms

我正在使用序列号字段作为查找值的公共字段,根据另一个表中的值更新表。但是,从以下2个查询中我得到两个不同的结果。有人可以解释为什么两个输出不同?更新语句不应该更新47200记录吗?

UPDATE TBL_SERIAL_NUMBER_MASTER A
SET (A.name) = (SELECT B.name 
                FROM TBL_DEVICE_LOCALITY B 
                WHERE A.SERIAL_NUMBER = B.SERIAL_NUMBER AND ROWNUM <=1 )
WHERE EXISTS ( SELECT 1 
               FROM TBL_DEVICE_LOCALITY 
               WHERE SERIAL_NUMBER = A.SERIAL_NUMBER 
                AND TBL_ODIN_DEVICE_LOCALITY.HOST_NAME IS NOT NULL );

结果int:更新了35,311行。

select count(*)
from TBL_SERIAL_NUMBER_MASTER A, TBL_DEVICE_LOCALITY B
WHERE A.SERIAL_NUMBER = B.SERIAL_NUMBER AND B.HOST_NAME IS NOT NULL;

返回:Count = 47200

1 个答案:

答案 0 :(得分:1)

首先,您应该学会使用正确的显式JOIN语法。所以,第二个查询应该是:

select count(*)
from TBL_SERIAL_NUMBER_MASTER A JOIN
     TBL_DEVICE_LOCALITY B
     ON A.SERIAL_NUMBER = B.SERIAL_NUMBER 
where B.HOST_NAME IS NOT NULL;

您收到的结果是因为两个查询不一样。您的结果表明SERIAL_NUMBER表中的B不是唯一的,因此JOIN是行的倍数。另一方面,UPDATE正在更新A中的行,而不管B中的匹配数量。

要比较喜欢,请使用:

select count(*)
from TBL_SERIAL_NUMBER_MASTER A JOIN
     TBL_DEVICE_LOCALITY B
     ON A.SERIAL_NUMBER = B.SERIAL_NUMBER 
where exists (select 1 
              from TBL_DEVICE_LOCALITY B
              where B.SERIAL_NUMBER = A.SERIAL_NUMBER AND
                    B.HOST_NAME IS NOT NULL
             );

或者,如果A中有唯一/主键列,则可以使用:

select count(distinct A.??)
from TBL_SERIAL_NUMBER_MASTER A JOIN
     TBL_DEVICE_LOCALITY B
     ON A.SERIAL_NUMBER = B.SERIAL_NUMBER 
where B.HOST_NAME IS NOT NULL;

其中??是唯一/主键列。