简体   繁体   中英

Using a self join to update a table with Oracle SQL

I'm trying to rewrite a MySQL update statement in Oracle. I am using Oracle SQL Developer version 20.4.1, and the MySQL code is:

UPDATE A
SET propertyaddress = ISNULL(A.propertyaddress, B.propertyaddress)
FROM nash_housing A
JOIN nash_housing B 
    ON A.parcelid = B.parcelid
    AND A.uniqueid_ <> B.uniqueid_
WHERE A.propertyaddress IS NULL;

I have tried the following variations of code:

MERGE INTO nash_housing A
USING nash_housing B
ON (
    A.parcelid = B.parcelid
    AND A.uniqueid_ <> B.uniqueid_
    )
WHEN MATCHED THEN UPDATE
SET A.propertyaddress = B.propertyaddress
WHERE A.propertyaddress IS NULL;

ERROR ORA-30926: unable to get a stable set of rows in the source tables

UPDATE nash_housing A
    SET A.propertyaddress = (SELECT DISTINCT B.propertyaddress
                                FROM nash_housing B
                                WHERE A.parcelid = B.parcelid
                                AND A.uniqueid_ <> B.uniqueid_)
WHERE A.propertyaddress IS NULL
AND EXISTS (SELECT 1
            FROM nash_housing B
            WHERE A.parcelid = B.parcelid
            AND A.uniqueid_ <> B.uniqueid_);

ERROR ORA-01427: single-row subquery returns more than one row

UPDATE
(SELECT A.propertyaddress AS OLD, B.propertyaddress AS NEW
    FROM nash_housing A
    JOIN nash_housing B
    ON A.parcelid = B.parcelid
    AND A.uniqueid_ <> B.uniqueid_
    WHERE A.propertyaddress IS NULL
    ) C
SET C.OLD = C.NEW;

ERROR SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table

Thanks for any and all help with this.

I think the second is closest. You just have to limit the subquery to one row:

UPDATE nash_housing n
    SET propertyaddress = (SELECT n2.propertyaddress
                           FROM nash_housing n2
                           WHERE n2.parcelid = n.parcelid AND
                                 n2.uniqueid_ <> n.uniqueid_ AND
                                 rownum = 1
                          )
    WHERE n.propertyaddress IS NULL AND
          EXISTS (SELECT n2.propertyaddress
                  FROM nash_housing n2
                  WHERE n2.parcelid = n.parcelid AND
                        n2.uniqueid_ <> n.uniqueid_
                 );

Note: Your table clearly has duplicates. The MySQL version is updating using an arbitrary matching row. The Oracle will do the same, although you might want to use an ORDER BY in the subquery to specify which row provides the value (such as the newest or oldest).

Also, I fixed the table aliases so they are meaningful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM