在具有不同值的多行上更新同一列

Posted

技术标签:

【中文标题】在具有不同值的多行上更新同一列【英文标题】:UPDATE ON SAME COLUMN ON MULTIPLE ROWS WITH DIFFERENT VALUES 【发布时间】:2017-10-11 14:05:14 【问题描述】:

下面是一个例子。表 1 是手动创建的,其中前三列是从外部文件加载到此处的。第四列 (SHOWROOM_ID) 将从 TABLE2 中获取,而 TABLE 1 中的其余列将根据标准进行更新。

表 1

NAME     |OLD_CPR_NO |OLD_COS_NO |SHOWROOM_ID|NM_CPR_COS_MAT|NM_CPR_MAT|COS_CPR_MAT|
------------------------------------------------------------------------------------
FORD     | 45        | 487       |           |              |          |    
TOYOTA   | 78        | 562       |           |              |          |
BENZ     | 55        | 789       |           |              |          |
JEEP     | 66        | 124       |           |              |          |
HONDA    | 34        | 142       |           |              |          |
KIA      | 12        | 962       |           |              |          |
GM       | 89        | 7787      |           |              |          |
CHRYSLER | 45        | 236       |           |              |          |
AUDI     | 67        | 4789      |           |              |          |

表 2

PK|NAME     |OLD_CPR_NO |OLD_COS_NO |SHOWROOM_ID
---------------------------------------------
1  |FORD     | 45        | 487       |   1    
2  |TOYOTA   | 78        | 562       |   2   
3  |CIAT     | 55        | 789       |   3     
4  |JEEP     | 66        | 124       |   5    
5  |HONDA    | 34        | 456       |   6   
6  |MUSTANG  | 12        | 962       |   7   
7  |GM       | 89        | 56        |   8   
8  |CHRYSLER | 45        | 236       |   9   
9  |AUDI     | 67        | 4789      |   10  

第 1 步: Update NM_CPR_COS_MAT column from table 1。这是一个指标字段,其中NAME,OLD_CPR_NO,OLD_COS_NO 匹配表 1 和表 2,然后分配指标“Y”

我能够根据以下查询获得结果:

UPDATE TABLE_1 TAB1
SET NM_CPR_COS_MAT = (SELECT 'Y'
FROM 
TABLE_2 TAB2
WHERE
TRIM(TAB1.NAME) = TRIM(TAB2.NAME)
AND TRIM(TAB1.OLD_CPR_NO) = TRIM(TAB2.OLD_CPR_NO)
AND TRIM(TAB1.OLD_COS_NO) = TRIM(TAB2.OLD_COS_NO)
;
COMMIT;

UPDATE TABLE_1 TAB1
SET SHOWROOM_ID= (SELECT TAB2.SHOWROOM_ID
FROM 
TABLE_2 TAB2
WHERE
TRIM(TAB1.NAME) = TRIM(TAB2.NAME)
AND TRIM(TAB1.OLD_CPR_NO) = TRIM(TAB2.OLD_CPR_NO)
AND TRIM(TAB1.OLD_COS_NO) = TRIM(TAB2.OLD_COS_NO)
AND TRIM(TAB1.NM_CPR_COS_MAT) = 'Y'
;
COMMIT;

结果:

TABLE 1
NAME     |OLD_CPR_NO |OLD_COS_NO |SHOWROOM_ID|NM_CPR_COS_MAT|NM_CPR_MAT|COS_CPR_MAT|
------------------------------------------------------------------------------------
FORD     | 45        | 487       |      1    |       Y      |          |    
TOYOTA   | 78        | 562       |      2    |       Y      |          |
BENZ     | 55        | 789       |           |              |          |
JEEP     | 66        | 124       |      5    |       Y      |          |
HONDA    | 34        | 142       |           |              |          |
KIA      | 12        | 962       |           |              |          |
GM       | 89        | 7787      |           |              |          |
CHRYSLER | 45        | 236       |     9     |       Y      |          |
AUDI     | 67        | 4789      |     10    |      Y       |          |

从下面的结果表中,我必须再次 UPDATE SHOWROOM_ID columnNM_CPR_MAT

TABLE 1
NAME     |OLD_CPR_NO |OLD_COS_NO |SHOWROOM_ID|NM_CPR_COS_MAT|NM_CPR_MAT|COS_CPR_MAT|
------------------------------------------------------------------------------------
FORD     | 45        | 487       |      1    |       Y      |          |    
TOYOTA   | 78        | 562       |      2    |       Y      |          |
BENZ     | 55        | 789       |           |              |          |
JEEP     | 66        | 124       |      5    |       Y      |          |
HONDA    | 34        | 142       |           |              |          |
KIA      | 12        | 962       |           |              |          |
GM       | 89        | 7787      |           |              |          |
CHRYSLER | 45        | 236       |     9     |       Y      |          |
AUDI     | 67        | 4789      |     10    |      Y       |          |

STEP 2:
UPDATE TABLE_1 TAB1
SET NM_CPR_MAT = (SELECT 'Y'
FROM 
TABLE_2 TAB2
WHERE
TRIM(TAB1.NAME) = TRIM(TAB2.NAME)
AND TRIM(TAB1.OLD_CPR_NO) = TRIM(TAB2.OLD_CPR_NO)
AND TRIM(NM_CPR_COS_MAT) IS NULL
;
COMMIT;

UPDATE TABLE_1 TAB1
SET SHOWROOM_ID= (SELECT TAB2.SHOWROOM_ID
FROM 
TABLE_2 TAB2
WHERE
WHERE
TRIM(TAB1.NAME) = TRIM(TAB2.NAME)
AND TRIM(TAB1.OLD_CPR_NO) = TRIM(TAB2.OLD_CPR_NO)
AND TRIM(NM_CPR_COS_MAT) IS NULL
AND TRIM(NM_CPR_MAT) = 'Y'
;
COMMIT;

我得到了以下结果。我在NM_CPR_MAT 列中得到了正确的“Y”,并且在SHOWROOM_ID 中得到了正确的数字以获取新的更新声明,但在先前更新的数字中已更新声明消失了。

TABLE 1
NAME     |OLD_CPR_NO |OLD_COS_NO |SHOWROOM_ID|NM_CPR_COS_MAT|NM_CPR_MAT|COS_CPR_MAT|
------------------------------------------------------------------------------------
FORD     | 45        | 487       |           |       Y      |          |    
TOYOTA   | 78        | 562       |           |       Y      |          |
BENZ     | 55        | 789       |           |              |          |
JEEP     | 66        | 124       |           |       Y      |          |
HONDA    | 34        | 142       |      6    |              |    Y     |
KIA      | 12        | 962       |           |              |          |
GM       | 89        | 7787      |      8    |              |    Y     |
CHRYSLER | 45        | 236       |           |      Y       |          |
AUDI     | 67        | 4789      |           |      Y       |          |

【问题讨论】:

并花一些时间学习如何格式化您在此网站上的帖子。如果你赶时间,那是你的问题;赶时间的时候不要在这里发帖。 【参考方案1】:

很难确定您何时发布了格式错误的 SQL,但似乎两个查询都更新了整个表。如果子查询条件与tab2 中的任何内容都不匹配,则更新将分配 null。所以第二个查询会覆盖第一个查询的结果。

您可以通过在第二个更新语句中添加 WHERE 条件来轻松解决此问题:

where SHOWROOM_ID is null

【讨论】:

以上是关于在具有不同值的多行上更新同一列的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如果存在则更新,否则插入...但对于具有不同值的多行

为啥在 oracle SQL 中,在条件相差很大的情况下,对同一列执行具有两个不同值的查询所花费的时间

SQL查询以选择在同一列中具有不同值的子记录的父级

从单个表中检索具有不同值的同一列的多个输出时的性能问题

SQL 更新表中的所有条目,但在列上插入不同的值

使用 BigQuery SQL 计算同一 ID 的所有列值的模式