具有多个条件和最大值的左联接

时间:2018-08-09 13:49:22

标签: oracle subquery max left-join outer-join

我正在尝试执行左联接,其中必须满足多个条件,其中包括拉入满足这些条件的MAX序列号。

左连接在两个表中的唯一标识符上。表acaps_history中的每个app_id都有几行。我只需要插入seq_number和activity_code最高的'XU'的一行。如果给定的app_id不存在代码“ XU”,则上述case语句应针对该行返回“ N”。我目前刚刚使用的代码无法正常工作-返回错误“列可能未在外部连接到子查询”:

create table orig_play3 as   
   (select 
    x.*, 
    case when xa.activity_code in 'XU' then 'Y' else 'N' end as cpo_flag

    from 
    dfs_tab_orig_play_x x

    left join cf.acaps_history xa on 
    x.APP_ID = xa.FOC_APPL_ID
    and xa.activity_code in 'XU'
    and xa.seq_number = (select max(seq_number) from cf.acaps_history where FOC_APPL_ID=x.app_id)
    )

3 个答案:

答案 0 :(得分:0)

鉴于您的错误,看来问题出在查询的最后一部分:

and xa.seq_number = (select max(seq_number) from cf.acaps_history where FOC_APPL_ID=x.app_id)

这仍然在ON子句的上下文中运行,因此查找最大序列号的子查询就是问题所在。

您应该可以通过将子查询移出ON子句来避免这种情况:

LEFT JOIN (
          SELECT FOC_APPL_ID, activity_code, seq_number
          FROM cf.acaps_history
          WHERE activity_code in 'XU'
) xa
ON x.APP_ID = xa.FOC_APPL_ID
WHERE xa.seq_number = (select max(ah.seq_number) from cf.acaps_history ah where ah.FOC_APPL_ID=x.app_id and ah.activity_code in 'XU')

答案 1 :(得分:0)

这可能是执行此查询的最无效的方法,但是它起作用了……运行大约花了3分钟(表大小超过60万行),但是它又返回了我需要的结果:

create table test as (
  select x.*,
  case when xb.activity_code in 'XU' then 'Y' else 'N' end as cpo_flag

  from dfs_tab_orig_play_x x

   left join
       (select 
       xa.FOC_APPL_ID, xa.activity_code, xa.seq_number
       from dfs_tab_orig_play_x x, cf.acaps_history xa
       where x.app_id = xa.FOC_APPL_ID (+)
       and xa.seq_number = (select max(seq_number) from cf.acaps_history where 
       x.app_id=FOC_APPL_ID(+) and activity_code in 'XU')) xb
   on x.app_id = xb.FOC_APPL_ID (+)
 )

答案 2 :(得分:0)

如果您使用12c,我喜欢OUTER APPLY,因为它可以让您对每个app_id降序为seq_number的行进行排序,然后选择最高的行

SELECT
    x.*,
    CASE
            WHEN xa.activity_code IN 'XU' THEN 'Y'
            ELSE 'N'
        END
    AS cpo_flag
FROM
    dfs_tab_orig_play_x x
    OUTER APPLY ( SELECT *
                  FROM   cf.acaps_history xa
                  WHERE  xa.foc_appl_id = x.app_id
                  AND    xa.activity_code = 'XU'
                  ORDER BY xa.seq_number DESC
                  FETCH FIRST 1 ROW ONLY ) xa

注意:此逻辑与您发布的内容略有不同。在此版本中,它将加入到给定acaps_history的'XU'记录中具有最高seq_number的{​​{1}}行中。对于给定的app_id,您的版本正在加入具有最高seq_number的行,无论该行是否为'XU'行。我假设(没有理由)那是您的错误。但是,如果不是这样,我的版本将无法正常工作。