Oracle SQL,试图从select / join中获取一个值来用于更新一个表中的一列?

时间:2014-05-07 13:32:12

标签: sql oracle sql-update dml

我有一个包含以下列的表:

T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_RESOLVED_SET_NUMBER
I_STATION_CODE
I_RESOLVED_START_MIN
I_DURATION
I_PERSON_NUMBER
I_COVIEW_DEMO_ID

最初,I_COVIEW_DEMO_ID设置为null。 然后我有另一个包含以下列的表:

T_RESOLVED_DATE
I_HOUSEHOLD_NUMBER
I_PERSON_NUMBER
I_AGE
T_GENDER
I_COVIEW_DEMO_ID

我正在尝试使用第二个表中的I_COVIEW_DEMO_ID值更新第一个表中的I_COVIEW_DEMO_ID,其中两个表中的T_RESOLVED_DATE,I_HOUSEHOLD_NUMBER和I_PERSON_NUMBER相等。第一个表可能包含多个具有相同DATE,HOUSEHOLD_NUMBER和PERSON_NUMBER的行,因为行可能会因其余列而异。

我试过做一个select和一个组,通过它看起来让我分道扬but,但当我尝试更新第一列时,我得到一个“单行子查询返回多行”错误表。这就是我尝试过的,以及它的变体:

UPDATE
  Table1
SET
    I_COVIEW_DEMO_ID =
(SELECT
    b.I_COVIEW_DEMO_ID
FROM Table1 a,
     Table2 b
WHERE a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER AND
      a.I_PERSON_NUMBER = b.I_PERSON_NUMBER AND
      a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
GROUP BY b.I_COVIEW_DEMO_ID);

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我能够使用此声明让它工作:

MERGE INTO table1 a
USING
(
   SELECT DISTINCT
      T_RESOLVED_DATE,
      I_HOUSEHOLD_NUMBER,
      I_PERSON_NUMBER,
      I_COVIEW_DEMO_ID
    FROM
      table2
) b
ON
(
  a.T_RESOLVED_DATE = b.T_RESOLVED_DATE
  AND a.I_HOUSEHOLD_NUMBER = b.I_HOUSEHOLD_NUMBER
  AND a.I_PERSON_NUMBER = b.I_PERSON_NUMBER
) WHEN MATCHED THEN
UPDATE SET
  a.I_COVIEW_DEMO_ID = b.I_COVIEW_DEMO_ID;

答案 1 :(得分:0)

根据我们对评论的讨论,这将是一个简单的PLSQL块,可以满足您的需求。我没有经过测试直接从头脑中做,所以你可能需要解决一些罪恶的错误。

BEGIN

    FOR rs IN ( SELECT I_HOUSEHOLD_NUMBER,
                       I_PERSON_NUMBER,
                       I_COVIEW_DEMO_ID,
                       T_RESOLVED_DATE
                FROM Table2 ) LOOP

        UPDATE Table1
           SET I_COVIEW_DEMO_ID = rs.I_COVIEW_DEMO_ID
         WHERE I_PERSON_NUMBER = rs.I_PERSON_NUMBER
           AND I_HOUSEHOLD_NUMBER = rs.I_HOUSEHOLD_NUMBER
           AND T_RESOLVED_DATE = rs.T_RESOLVED_DATE;

    END LOOP;
    --commit after all updates, if there is many rows you should consider in
    --making commits by blocks. Define a count and increment it whithin the for
    --after some number of updates you commit and restart the counter
    COMMIT;

END;