Update 两个表之间数据更新

今天遇到一个问题,就是在原来的一个表的基础上增加两个字段,并且根据历史数据和一个计算方法把这两个字段补齐。
到网上查了一下。

一、当用一个表中的数据来更新另一个表中的数据,T-SQL提供多种写法(下面列出了二种),但建议用第一种写法,虽然传统,但结构清晰

并且要注意,当用一个表中的数据来更新另一个表中的数据时,二个表一定要有关联!

1.

update t1 
        set t1.c2 = t2.c2
      from t2

where t1.c1 = t2.c1

2.

Update t1 
        set t1.c2 = t2.c2

from t1 inner join t2 
        on t1.c1 = t2.c1

二、FROM 子句中指定的表的别名不能作为 SET column_name 子句中被修改字段的限定符使用
    例如,下面的内容无效:

UPDATE titles

SET t.ytd_sales = t.ytd_sales + s.qty

FROM titles t, sales s

WHERE t.title_id = s.title_id

AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

若要使上例合法,请从列名中删除别名 t 或使用本身的表名

1.

UPDATE titles

SET ytd_sales = t.ytd_sales + s.qty

FROM titles t, sales s

WHERE t.title_id = s.title_id

AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

2.

UPDATE titles

SET titles.ytd_sales = t.ytd_sales + s.qty

FROM titles t, sales s

WHERE t.title_id = s.title_id

AND s.ord_date = (SELECT MAX(sales.ord_date) FROM sales)

<think> 我们正在处理一个关于Oracle数据更新两个查询对比结果的问题。根据用户的问题,用户希望知道如何更新两个之间查询对比的结果。结合提供的引用内容,我们可以提取以下有用信息: - 引用[1]提到在Oracle中两个更新时,如果SQL语句写成某种形式,Oracle不会通过。这提示我们需要使用正确的语法来实现更新。 - 引用[2]展示了一个从两个查询数据并插入到另一个的例子,这虽然是一个插入操作,但可以借鉴其多连接查询的方式。 - 引用[3]讨论了Oracle的数据完整性约束,特别是实体完整性,以及如何通过主键来保证数据的唯一性。这提醒我们在更新操作中需要注意数据唯一性。 根据这些引用和用户的问题,我们需要使用UPDATE语句结合多连接来更新两个对比的结果。在Oracle中,更新多个的一种常见方法是使用子查询或使用可更新的连接视图(需要满足一定条件)。但更通用的方法是使用MERGE语句或者通过子查询来更新一个,然后更新另一个(分两次更新)。 然而,用户的问题是关于“更新两个查询对比的结果”,这意味着用户可能想要根据两个的对比结果来更新其中一个两个。根据常见的数据库操作,我们通常只能在一个UPDATE语句中更新一个。如果需要更新两个,则需要两个独立的UPDATE语句。 这里我们假设用户想要根据两个数据对比来更新其中一个的某些数据。例如,A和B,我们根据对比的结果更新A。 在Oracle中,可以使用以下方法: 1. 使用子查询进行更新:在UPDATE语句的SET或WHERE子句中使用子查询来引用另一个。 2. 使用MERGE语句:MERGE语句可以同时进行更新和插入操作,特别适合根据另一个数据更新目标。 由于引用[1]提到更新时SQL语句写法问题,我们需要特别注意语法。例如,正确的更新语法可能是: ```sql UPDATE table1 t1 SET t1.column = (SELECT expression FROM table2 t2 WHERE t2.key = t1.key) WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t2.key = t1.key); ``` 或者使用MERGE语句: ```sql MERGE INTO table1 t1 USING table2 t2 ON (t1.key = t2.key) WHEN MATCHED THEN UPDATE SET t1.column = t2.column; ``` 但是,如果用户想要更新两个(即同时更新A和B),那么我们需要两个UPDATE语句,并且可能需要在事务中执行以保证数据一致性。 由于用户问题描述不够具体,我们假设用户希望根据两个的对比结果更新其中一个。下面我们将给出一个使用MERGE语句更新一个的例子。 注意:在实际操作前,请确保有备份或在测试环境中验证。 假设我们有两个:employees(员工)和employees_temp(临时),我们想要根据临时中的新工资更新员工中的工资。 ```sql MERGE INTO employees e USING employees_temp t ON (e.employee_id = t.employee_id) WHEN MATCHED THEN UPDATE SET e.salary = t.salary; ``` 如果用户需要根据两个的对比结果更新两个,那么我们可以分别执行两个更新操作,例如: ```sql -- 更新A UPDATE tableA a SET a.column1 = (SELECT b.column1 FROM tableB b WHERE b.id = a.id) WHERE EXISTS (SELECT 1 FROM tableB b WHERE b.id = a.id); -- 更新B UPDATE tableB b SET b.column2 = (SELECT a.column2 FROM tableA a WHERE a.id = b.id) WHERE EXISTS (SELECT 1 FROM tableA a WHERE a.id = b.id); ``` 或者在一个事务中执行这两个更新。 由于引用[3]提到了主键约束,我们在更新时应该确保连接条件使用唯一键(如主键)以避免更新多行。 根据用户的问题,我们给出一个通用的步骤: 1. 明确要更新的目标以及更新规则(根据哪个的哪个字段更新)。 2. 确保两个之间存在可以关联的字段(如主键或外键)。 3. 使用合适的UPDATE语句或MERGE语句进行更新。 如果用户需要更具体的帮助,比如提供结构,我们可以给出更精确的SQL语句。 下面根据用户的问题生成相关问题: §§相关问题§§ 1. 在Oracle中,如何同时更新两个数据? 2. 使用MERGE语句更新数据时需要注意哪些问题? 3. 如何避免在更新两个时出现死锁? 4. 在更新两个时,如何保证数据的一致性? </think> 在Oracle中更新两个查询对比的结果,可以通过以下方法实现: ### 方法1:使用MERGE语句(推荐) ```sql MERGE INTO table1 t1 USING ( SELECT t1.id, t2.new_value FROM table1 t1 JOIN table2 t2 ON t1.key = t2.key WHERE t1.value <> t2.value -- 对比条件 ) diff ON (t1.id = diff.id) WHEN MATCHED THEN UPDATE SET t1.value = diff.new_value; ``` **说明**: 1. `USING`子句创建对比数据集 2. `ON`指定连接条件 3. `WHEN MATCHED`执行更新 4. 自动处理匹配行,效率较高[^1] ### 方法2:使用子查询更新 ```sql UPDATE table1 t1 SET t1.value = ( SELECT t2.new_value FROM table2 t2 WHERE t1.key = t2.key AND t1.value <> t2.value -- 对比条件 ) WHERE EXISTS ( SELECT 1 FROM table2 t2 WHERE t1.key = t2.key AND t1.value <> t2.value ); ``` **注意**: - `WHERE EXISTS`确保只更新有差异的记录 - 需处理NULL值(使用`NVL`函数) - 大操作时注意性能[^2] ### 关键要点: 1. **连接条件**:必须明确两关联字段(如主键/外键) 2. **对比逻辑**:使用`<>`或`!=`标识差异字段 3. **数据一致性**:建议在事务中执行 ```sql BEGIN -- 更新语句 COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; END; ``` 4. **性能优化**: - 更新前创建索引(尤其在关联字段上) - 使用`MERGE`替代多语句操作 - 分批更新大量数据[^3] > **实践建议**: > 对于复杂对比逻辑,可先创建临时存储对比结果: > ```sql > CREATE GLOBAL TEMPORARY TABLE diff_results AS > SELECT t1.id, t2.correct_value > FROM table1 t1 > JOIN table2 t2 ON t1.key = t2.key > WHERE t1.status <> t2.status; > > UPDATE table1 t1 > SET t1.status = (SELECT correct_value FROM diff_results d WHERE d.id = t1.id) > WHERE EXISTS (SELECT 1 FROM diff_results d WHERE d.id = t1.id); > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值