SQL (oracle) 使用另一个 table 中的值更新 table 中的一些记录

SQL (oracle) Update some records in table using values in another table

我要表 :

Table1
--------------------------------
ID         VAL1       DATE1
--------------------------------
1          1          20/03/2015
2          null       null
3          1          10/01/2015
4          0          12/02/2015
5          null       null

Table2
--------------------------------
ID         VAL2       DATE1
--------------------------------
1          N          02/06/2015
1          N          01/08/2015
2          null       null
3          O          05/04/2016
3          O          02/02/2015
4          O          01/07/2015
5          O          03/02/2015
5          N          10/01/2014
5          O          12/04/2015

我要更新:

(这两个表不是那么简单,只是为了说明,可以用ID列连接)。

这是我的代码:

UPDATE Table1 t1
SET t1.VAL1 = '0',
t1.DATE1 = (select min(t2.DATE2) --To take the first DATE for each ID where VAL2='O' (not working fine)
            FROM Table2 t2, Table1 t1
            WHERE trim(t2.ID) = trim(t1.ID)
            AND VAL2='O')
WHERE EXISTS (SELECT NULL
              FROM Table2 t2
              WHERE trim(t2.ID) = trim(t1.ID)
              AND t2.Table2 = 'O')
AND VAL1<>'0'; --(for doing the update only if VAL1 not already equal to 0)

预期结果是:

Table1
--------------------------------
ID         VAL1       DATE1
--------------------------------
1          1          20/03/2015
2          null       null
3          0          02/02/2015
4          0          01/07/2015
5          0          10/01/2014

我得到的结果是:

Table1
--------------------------------
ID         VAL1       DATE1
--------------------------------
1          1          20/03/2015
2          null       null
3          0          10/01/2014
4          0          10/01/2014
5          0          10/01/2014

我的问题是无论 ID 是什么,DATE1 总是更新为同一日期。

您不应该在第一个子查询中第二次引用 table1;这正在失去子查询和外部查询之间的相关性。如果您 运行 子查询本身,它总是会在 table2 中为 任何 ID 在 [=11= 中具有 val2='O' 的 ID 找到最低日期],即 10/01/2014。 (除非您的示例数据不一致;那实际上是 N 所以不会被考虑 - 您当前和预期的结果与您显示的数据不匹配,但您说它不是真实的)。符合更新条件的每一行 运行 都是相同的子查询并获得相同的值。

您需要维护外部查询和子查询之间的相关性,因此子查询应该使用外部 table1 进行连接,就像第二个子查询已经做的那样:

UPDATE Table1 t1
SET t1.VAL1 = '0',
t1.DATE1 = (select min(t2.DATE2)
            FROM Table2 t2
            WHERE trim(t2.ID) = trim(t1.ID)
            AND VAL2='O')
WHERE EXISTS (SELECT NULL
              FROM Table2 t2
              WHERE trim(t2.ID) = trim(t1.ID)
              AND t2.Val2 = 'O')
AND VAL1<>'0';

您可以使用此 UPDATE 语句。

UPDATE TABLE1 T1
SET T1.VAL1 = '0',
T1.DATE1 = (SELECT MIN(T2.DATE2) 
                  FROM TABLE2 T2
                  WHERE TRIM(T2.ID) = TRIM(T1.ID)
                  AND T2.VAL2='O')
WHERE T1.ID IN (SELECT T2.ID FROM TABLE2 T2 WHERE T2.VAL2='O')

希望对您有所帮助。

MYSQL解决方案

希望这个 MySql 语法也适用于 ORACLE。

SQL 的问题是它在计算最早日期时只考虑带有 VAL2=='O' 的记录。所以最后一条记录的日期如下面 table 所示。不考虑记录“5 N 10/01/2014”。

UPDATE Table1, (SELECT * FROM (SELECT * FROM table2 WHERE VAL2='O' ORDER BY ID, DATE1) X GROUP BY X.ID) T2
SET Table1.DATE1=T2.DATE1, Table1.VAL1=0
WHERE Table1.ID=T2.ID

..

Table1
--------------------------------
ID         VAL1       DATE1
--------------------------------
1          1          20/03/2015
2          null       null
3          0          02/02/2015
4          0          01/07/2015
5          0          **03/02/2015**

在 MySql 5.6.14

上测试