我们有两张桌子:

Table A (ID, NAME)
1, 'NAME1'
2, 'NAME1'
3, 'NAME2'
4, 'NAME2'

Table B (ID, NAME)
NULL, 'NAME1'
NULL, 'NAME1'
NULL, 'NAME2'
NULL, 'NAME2'

如何用表A的ID更新表B,而不会出现单行子查询错误?

传统更新不起作用,单行子查询错误.

推荐答案

您可以使用ROW_NUMBER分析函数对两个表中每个名称的行进行编号,然后根据名称和行号进行联接,然后使用MERGE语句更新与ROWID伪列相关的现有表,以唯一匹配每一行:

MERGE INTO table_b dst
USING (
  SELECT a.id,
         b.rid
  FROM   (
           SELECT id,
                  name,
                  ROW_NUMBER() OVER (PARTITION BY name ORDER BY id, ROWNUM) AS rn
           FROM   table_a
         ) a
         INNER JOIN (
           SELECT ROWID as rid,
                  name,
                  ROW_NUMBER() OVER (PARTITION BY name ORDER BY id, ROWNUM) AS rn
           FROM   table_b
         ) b
         ON a.name = b.name AND a.rn = b.rn
) src
ON (src.rid = dst.ROWID)
WHEN MATCHED THEN
  UPDATE
  SET id = src.id;

其中,对于样本数据:

CREATE TABLE Table_A (ID, NAME) AS
SELECT 1, 'NAME1' FROM DUAL UNION ALL
SELECT 2, 'NAME1' FROM DUAL UNION ALL
SELECT 3, 'NAME2' FROM DUAL UNION ALL
SELECT 4, 'NAME2' FROM DUAL;

CREATE TABLE Table_B (ID, NAME) AS
SELECT CAST(NULL AS NUMBER), 'NAME1' FROM DUAL UNION ALL
SELECT NULL, 'NAME1' FROM DUAL UNION ALL
SELECT NULL, 'NAME2' FROM DUAL UNION ALL
SELECT NULL, 'NAME2' FROM DUAL;

然后,在MERGE之后,表B载有:

ID NAME
1 NAME1
2 NAME1
3 NAME2
4 NAME2

fiddle

Sql相关问答推荐

如何将多个 Select 查询从一个表中组合出来

如何转换和汇总行数

使用sede获取不一定有两个不同标签的所有问题

为什么两个不同的窗口函数给出不同的排序结果?

PostgreSQL中的合并命令是原子的,还是需要一些类似于SQL Server版本的内容?

防止ActiveRecord迁移在db/structure.sql中进行巨大更改

将FLOAT转换为VARBINARY,然后再转换回FLOAT

统计PostgreSQL中前10个最大大小表的行数

从JSON值数组创建扁平数组Athena

SQL OR子句如何在JOINON查询中工作?

对现有记录进行分组

统计重复记录的总数

POSTGRES to_timestamp() 假定 UTC 字符串为本地时间

Oracle SQL:通过将日期与另一个表行进行比较来 Select 值

获取记录的上一个值,并将其与当前值一起显示

如何使用Informix创建一个临时表,将数据从根表导入并使用筛选条件

MariaDB非常简单的MATCHAGAINST查询不使用FULLTEXT索引吗?

如何在 SQL Server 中将 -13422.8450 舍入到 -13422.84

条件意外地显着降低性能的地方

ACCESS SQL - 有没有办法使用通配符仅 Select 字段的特定部分?