SQL(oracle)使用另一个表

时间:2016-01-14 23:09:00

标签: sql oracle oracle-sqldeveloper

我需要表格:

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

我想更新:

  • 列VAL1(表1)与' 0',如果VAL2(表2)等于' O'
  • 列DATE1(表1),每个ID最早的DATE2(表2)(这里是我的问题)

(这两个表不是那么简单,只是为了说明,它们可以与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始终使用相同的日期进行更新。

3 个答案:

答案 0 :(得分:1)

您不应该在第一个子查询中第二次引用table1;这会丢失子查询和外部查询之间的相关性。如果您自己运行子查询,它将始终在table2中找到 val2='O'table1的任何 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';

答案 1 :(得分:1)

您可以使用此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')

希望它会对你有所帮助。

答案 2 :(得分:0)

MYSQL解决方案

希望MySql语法也适用于ORACLE。

SQL的问题在于它只考虑VAL2 ==&#39; O&#39;的记录。在计算最早的日期时。所以最后一条记录的日期如下表所示。记录&#34; 5 N 10/01/2014&#34;不予考虑。

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上测试