【问题标题】:Update multiple rows in the target table from one row in the source table using a natural key使用自然键从源表中的一行更新目标表中的多行
【发布时间】:2019-10-07 08:56:00
【问题描述】:

我需要使用维度表中的数据更新 FACT 表中的两列。挑战在于我没有匹配两个表的主键,所以我必须使用自然键,两列来创建唯一值。除了源有一条记录,目标有多条记录。如果我进行合并,我会得到 ​​p>

ora-30926 无法获得稳定的行集

如果我进行更新,我会收到另一个错误。请问我需要帮助。

我试试这个更新声明:

UPDATE dw.target_table obc
SET
( obc.sail_key,
  obc.durations ) = (
    SELECT 
        sd.sail_key,
        sd.durations
    FROM
        dw.source_table sd
    WHERE
        obc.code_1 = sd.code_2
        AND obc.date_1 = sd.date_2
)
WHERE
obc.item NOT IN (
    30,
    40
)
AND obc.sail_key = 0
and OBC.load_date between to_date('01-12-2018','DD-MM-YYYY') 
AND  to_date ('31-12-2018','DD-MM-YYYY');

我试试这个合并语句:

   MERGE INTO dw.target_table obc 
  USING ( SELECT distinct
                  code_2,date_2,durations,sail_key
          FROM dw.source_table
   ) tb_dim 
  ON ( obc.code_1 = tb_dim.code_2
  AND obc.date_1 = tb_dim.date_2 )
    WHEN MATCHED THEN UPDATE SET obc.durations = tb_dim.durations,
  obc.sail_key = tb_dim.sail_key
 WHERE
obc.sail_key = 0
AND obc. NOT IN (
    30,
    40
)
AND obc.loaddate BETWEEN TO_DATE('01-01-2012','DD-MM-YYYY') 
AND TO_DATE  ('31-01-2012','DD-MM-YYYY');

【问题讨论】:

  • 与 UPDATE 示例相比,您的 MERGE 示例交换了 dw.target_tabledw.source_table 的角色。我已经编辑了 MERGE 示例以使其有意义。为了将来参考,在编辑代码时请注意确保成品的一致性和连贯性。您发布的内容就是我们所要做的。

标签: sql oracle oracle11g


【解决方案1】:

ora-30926 无法获得稳定的行集

这意味着(code_2,date_2) 不是 tb_dim 的唯一键。因此,您的 USING 子查询不会生成仅将一行与 obc 中的任何行匹配的集合。因此 MERGE 失败,因为 Oracle 无法确定 USING 子查询中的哪一行应该应用于目标。 DISTINCT 没有帮助,因为它应用于整个投影,而且对于 code_2,date_2 的每个排列,您似乎有多个不同的 durations,sail_key 值。

您没有说明在运行 UPDATE 时遇到了哪个错误,但可能是 ORA-01779 或 ORA-01427。指示子查询的内容未返回一组连接键。

那么你如何解决这种情况?我们无法为您提供正确的解决方案,因为这是您的数据模型或规范的失败。解决需要了解您的业务,而我们没有。但通常你需要找到一个额外的规则,将 USING 子查询减少到一个集合。那就是:

  • 添加第三个键列,允许 ON 子句将tb_dim 中的一行映射到obc 中的一行;或
  • 在子查询中使用row_number()分析函数来伪造这样的列,最好按日期等有意义的列排序;或
  • 在子查询中添加条件 WHERE 子句以删除 code_2,date_2 的重复值。

或者,如果您不关心应用了 durations,sail_key 的哪些特定值,您可以使用聚合:

USING (SELECT code_2
              ,date_2
              ,max(durations) as durations
              ,max(sail_key) as sail_key
       FROM dw.source_table
       group by code_2,date_2 ) tb_dim

使用对您有意义的任何功能。

【讨论】:

  • 感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多