Oracle SQL或PL / SQL相关的更新列值是/否

时间:2018-10-10 18:30:59

标签: oracle sql-update

我试图通过相关更新来更新具有多个值(Y / N)的单列并出现错误,可以使用:

  

ORA-01427:单行子查询返回多个行。

我有两个桌子。

REQUESTS_TABLE

+-------------+------+
| CUSTOMER_ID | FLAG |
+-------------+------+
|         200 |      |
|         900 |      |
+-------------+------+

CREDITS_TABLE

+-------------+---------------+
| CUSTOMER_ID | CUSTOMER_NAME |
+-------------+---------------+
|         100 | John          |
|         200 | Smith         |
|         300 | Mary          |
|         400 | David         |
|         500 | Jake          |
+-------------+---------------+

如果贷方表中存在请求表中的customer_id,那么我想将请求表中的“ FLAG”列更新为“ Y”。如果找不到,则为“ N”。下面是试图获取的输出:

输出: REQUESTS_TABLE

+-------------+------------+
| CUSTOMER_ID | FOUND_FLAG |
+-------------+------------+
|         200 | Y          |
|         900 | N          |
+-------------+------------+

下面是我尝试过的查询,导致错误:

UPDATE requests_table r 
SET    ( flag ) = (SELECT CASE 
                            WHEN c.customer_id IS NOT NULL THEN 'Y' 
                            ELSE 'N' 
                          END 
                   FROM   credits_table c 
                   WHERE  c.customer_id = r.customer_id) 
WHERE  EXISTS (SELECT * 
               FROM   credits_table c 
               WHERE  c.customer_id = r.customer_id) 

当我在线搜索帮助时,我发现查询会更新多个列,但不会更新单个列中的多个值。因此,在这里寻求帮助。

感谢任何帮助。

谢谢,
里查

2 个答案:

答案 0 :(得分:2)

您可以使用:

UPDATE requests_table
SET found_flag = CASE WHEN EXISTS(SELECT c.customer_id FROM credits_table c 
                                 WHERE c.customer_id = requests_table.customer_id)
                      THEN 'Y'
                      ELSE 'N'
                 END

答案 1 :(得分:1)

您最好将其作为两个语句来完成(最好是在单个事务中完成):

UPDATE requests_table
SET    found_flag = 'N';

UPDATE requests_table
SET    found_flag = 'Y'
WHERE  EXISTS
           (SELECT *
            FROM   credits_table c
            WHERE  c.customer_id = requests_table.customer_id);

这可能比@LukaszSzozda的答案执行得更好,因为它避免了需要为requests_table中的每一行运行的嵌套子查询。


在单个查询中执行此操作的另一种方法应该是具有相当的速度,即使用merge(除最简单的更新外,我倾向于在所有merge上使用update )。

MERGE INTO requests_table
USING      (SELECT rt.customer_id,
                   CASE WHEN c.customer_id IS NULL THEN 'N' ELSE 'Y' END
                       AS found_flag
            FROM   requests_table rt
                   LEFT JOIN credits_table c
                       ON c.customer_id = rt.customer_id) src
ON         (requests_table.customer_id = src.customer_id)
WHEN MATCHED THEN
    UPDATE SET found_flag = src.found_flag