Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 当键在另一个表中有多个条目时,基于联接更新列_Sql_Oracle - Fatal编程技术网

Sql 当键在另一个表中有多个条目时,基于联接更新列

Sql 当键在另一个表中有多个条目时,基于联接更新列,sql,oracle,Sql,Oracle,我有一个表,其中我必须根据到另一个表的联接更新列。然而,问题是键在另一个表中不是唯一的,因此联接返回多个值。我是个新手,想不出有什么解决办法。我尝试了一个基于连接的普通更新,但它返回了一个错误,即子查询返回多个值)请帮助! (我在Oracle上工作) 例如 表A ID|pc 1| 2| 3| 4| ID pc 1 a 1 b

我有一个表,其中我必须根据到另一个表的联接更新列。然而,问题是键在另一个表中不是唯一的,因此联接返回多个值。我是个新手,想不出有什么解决办法。我尝试了一个基于连接的普通更新,但它返回了一个错误,即子查询返回多个值)请帮助! (我在Oracle上工作)
例如
表A

ID|pc       
 1|         
 2|         
 3|         
 4|         
ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
表B

Id|pc
 1|a            
 1|b
ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
更新后,我需要使表格看起来像这样。
表A

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              

这是一个棘手的问题,因为您得到的主要参考是id,但对于匹配的id,您将需要更新记录和插入记录

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
这将对指定的数据起作用,但请注意,不能多次运行此查询。一旦信息合并到TableA中,此查询将无法再次更新它。也许也有办法做到这一点,但由于给定的问题相当抽象,我不知道什么是最好的解决方案

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
merge into TableA a
using
 (select id, pc, dense_rank() over (partition by id, order by pc) as nr
  from tableB) b
on (b.id = a.id and b.nr = 1)
when matched then
  update set a.pc = b.pc
when not matched then
  insert(id, pc) values (b.id, b.pc)

或者,您可以定义PL/SQL程序块来更新此数据。然后可以使用游标或语句集合来更新表,这可能更容易,比尝试编写单个SQL语句更灵活、可读性更强。

如果
表B
中的
pc
值是唯一的,并且
表a
中的初始值是
NULL
或者不是
表B
值的重复项,那么GolezTrol的方法就可以正常工作。但是,如果
表B
中或两个表之间存在重复值,请尝试以下操作:

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
Oracle 11g R2架构设置

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
CREATE TABLE Table_A (ID NUMBER(1),pc CHAR(1));
CREATE TABLE Table_B (ID NUMBER(1),pc CHAR(1));

INSERT INTO Table_A
          SELECT 1, NULL FROM DUAL
UNION ALL SELECT 2, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 4, NULL FROM DUAL;

INSERT INTO Table_B
          SELECT 1, 'a' FROM DUAL
UNION ALL SELECT 1, 'b' FROM DUAL
UNION ALL SELECT 2, 'b' FROM DUAL
UNION ALL SELECT 2, 'c' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL;
SELECT * FROM Table_A ORDER BY ID, pc
| ID |     PC |
|----|--------|
|  1 |      a |
|  1 |      b |
|  2 |      a |
|  2 |      b |
|  2 |      c |
|  3 |      a |
|  3 |      a |
|  3 |      a |
|  4 | (null) |
查询1

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
CREATE TABLE Table_A (ID NUMBER(1),pc CHAR(1));
CREATE TABLE Table_B (ID NUMBER(1),pc CHAR(1));

INSERT INTO Table_A
          SELECT 1, NULL FROM DUAL
UNION ALL SELECT 2, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 4, NULL FROM DUAL;

INSERT INTO Table_B
          SELECT 1, 'a' FROM DUAL
UNION ALL SELECT 1, 'b' FROM DUAL
UNION ALL SELECT 2, 'b' FROM DUAL
UNION ALL SELECT 2, 'c' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL;
SELECT * FROM Table_A ORDER BY ID, pc
| ID |     PC |
|----|--------|
|  1 |      a |
|  1 |      b |
|  2 |      a |
|  2 |      b |
|  2 |      c |
|  3 |      a |
|  3 |      a |
|  3 |      a |
|  4 | (null) |
第一个
行编号
处理插入不匹配的行(即使存在相同值的多个副本)

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
第二个
行编号
处理插入现有值的重复项-如果
表A
已经包含(ID.x,pc.y)并且
表B
包含该值的多个重复项,则第一个值将被覆盖,随后将追加
表B
中的重复项

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
MERGE INTO Table_A dst
USING (SELECT ID,
              pc,
              ROW_NUMBER() OVER (PARTITION BY ID ORDER BY pc) AS rn,
              ROW_NUMBER() OVER (PARTITION BY ID, pc ORDER BY pc) AS rnx
       FROM   Table_B) src
ON (     dst.ID = src.ID
    AND (   (dst.pc = src.pc AND src.rnx = 1)
         OR (dst.pc IS NULL  AND src.rn = 1)
        )
   )
WHEN MATCHED THEN
  UPDATE SET dst.pc = src.pc
WHEN NOT MATCHED THEN
  INSERT (ID, pc) VALUES (src.ID, src.pc)

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
CREATE TABLE Table_A (ID NUMBER(1),pc CHAR(1));
CREATE TABLE Table_B (ID NUMBER(1),pc CHAR(1));

INSERT INTO Table_A
          SELECT 1, NULL FROM DUAL
UNION ALL SELECT 2, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 4, NULL FROM DUAL;

INSERT INTO Table_B
          SELECT 1, 'a' FROM DUAL
UNION ALL SELECT 1, 'b' FROM DUAL
UNION ALL SELECT 2, 'b' FROM DUAL
UNION ALL SELECT 2, 'c' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL;
SELECT * FROM Table_A ORDER BY ID, pc
| ID |     PC |
|----|--------|
|  1 |      a |
|  1 |      b |
|  2 |      a |
|  2 |      b |
|  2 |      c |
|  3 |      a |
|  3 |      a |
|  3 |      a |
|  4 | (null) |
查询2

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
CREATE TABLE Table_A (ID NUMBER(1),pc CHAR(1));
CREATE TABLE Table_B (ID NUMBER(1),pc CHAR(1));

INSERT INTO Table_A
          SELECT 1, NULL FROM DUAL
UNION ALL SELECT 2, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 4, NULL FROM DUAL;

INSERT INTO Table_B
          SELECT 1, 'a' FROM DUAL
UNION ALL SELECT 1, 'b' FROM DUAL
UNION ALL SELECT 2, 'b' FROM DUAL
UNION ALL SELECT 2, 'c' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL;
SELECT * FROM Table_A ORDER BY ID, pc
| ID |     PC |
|----|--------|
|  1 |      a |
|  1 |      b |
|  2 |      a |
|  2 |      b |
|  2 |      c |
|  3 |      a |
|  3 |      a |
|  3 |      a |
|  4 | (null) |

ID    pc            
 1     a            
 1     b            
 2              
 3              
 4              
CREATE TABLE Table_A (ID NUMBER(1),pc CHAR(1));
CREATE TABLE Table_B (ID NUMBER(1),pc CHAR(1));

INSERT INTO Table_A
          SELECT 1, NULL FROM DUAL
UNION ALL SELECT 2, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 4, NULL FROM DUAL;

INSERT INTO Table_B
          SELECT 1, 'a' FROM DUAL
UNION ALL SELECT 1, 'b' FROM DUAL
UNION ALL SELECT 2, 'b' FROM DUAL
UNION ALL SELECT 2, 'c' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL
UNION ALL SELECT 3, 'a' FROM DUAL;
SELECT * FROM Table_A ORDER BY ID, pc
| ID |     PC |
|----|--------|
|  1 |      a |
|  1 |      b |
|  2 |      a |
|  2 |      b |
|  2 |      c |
|  3 |      a |
|  3 |      a |
|  3 |      a |
|  4 | (null) |

您不仅要更新TableA,还要插入一条新记录。@GolezTrol是的。这就是目的。如果这个问题看起来不清楚,我很抱歉。有什么方法可以达到这个结果吗?非常感谢你的帮助!(对我来说)这个问题肯定远远超出了初学者的水平,不像我想的那样两个问题:
densite\u-RANK
如果具有相同的值,则会生成具有相同列的多行,这可能会触发同一行的多次更新-切换到
row\u-NUMBER
可以解决此问题;如果
Table_A
已经有一个非空的
pc
值,那么匹配将用
Table_B
中排名第一的
pc
值覆盖它。关于稠密等级的好观点。我想我通过这个问题假设id/pc的组合在表B中是唯一的。