使用自然键从源表中的一行更新目标表中的多行

时间:2019-05-21 02:11:52

标签: sql oracle oracle11g

我需要使用维度表中的数据更新FACT表中的两列。挑战在于我没有一个与两个表都匹配的主键,因此我必须使用一个自然键,两列来创建唯一值。除了源有一个记录,目标还有多个记录。如果合并,我将得到

  

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');

1 个答案:

答案 0 :(得分:1)

  

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

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

您没有说运行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

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