在此sql查询中添加另一个连接

时间:2015-03-11 01:21:54

标签: sql oracle

以下查询大约需要3分钟才能完成。但是现在要求在SELECT中获取另一个属性,该属性位于不同的表中。

我认为我必须在ACCOUNT_CYCLE_ACTIVITY表上另外加入,但是这里的account_id上的简单连接需要执行时间从3分钟到超过一个小时。

有什么方法可以让它跑得更快?

SELECT *
 FROM ACCOUNT_CYCLE_ACTIVITY aca 
 inner join card_account ca 
    on aca.account_id = ca.ACCOUNT_ID
    and aca.ACTIVITY_TYPE_CODE in ('011', '021', '007') 
    and aca.ACTIVITY_GROUP_CODE= 'R12'
    and (aca.CYCLE_ACTIVITY_AMOUNT) > 25 
    and aca.CYCLE_ACTIVITY_COUNT =1
    and aca.cycle_ctr = ca.cycle_ctr - 1
 left join ACCOUNT_CYCLE_ACTIVITY aca2
        on aca2.account_id            = aca.ACCOUNT_ID
        and aca2.ACTIVITY_TYPE_CODE  = aca.activity_type_code 
        and aca2.ACTIVITY_GROUP_CODE = aca.activity_group_code
        and aca2.CYCLE_ACTIVITY_COUNT = 1
        and aca2.cycle_ctr between aca.cycle_ctr - 6 and aca.cycle_ctr - 1

where aca2.ACCOUNT_ID is null;

1 个答案:

答案 0 :(得分:0)

我尝试使用您的查询,下面是有希望的事情。我在第一个子查询中使用self-join(正如@Gordon Linoff在评论中怀疑的那样)消除了lag()并在主查询中过滤了此虚拟列。查询返回返回您的行的相同行,但请比较实际数据。

with aca as (
  select a.*, lag(cycle_ctr) over (
        partition by account_id, activity_type_code, activity_group_code 
        order by cycle_ctr ) as pcc
    from account_cycle_activity a 
    where activity_type_code in ('011', '021', '007') and activity_group_code = 'R12' 
      and cycle_activity_amount > 25 and cycle_activity_count = 1
  )
select aca.account_id, aca.cycle_ctr, aca.activity_type_code, activity_group_code
  from aca 
    join card_account ca 
      on ca.account_id = aca.account_id and ca.cycle_ctr - 1 = aca.cycle_ctr
  where pcc is null or pcc-aca.cycle_ctr not between -6 and -1

至于你问题的这一部分:

  

现在要求在SELECT中获取另一个属性   位于不同的表格中

我必须知道应该做些什么,请更准确,如果需要,可以编辑原始问题。

我认为评论中提到的索引在这里非常重要,但如果没有数据访问,很难说哪个是最好的。

我使用的表结构和样本数据如下所示。如果您发现数据与我的数据之间存在任何差异,请在两个表中添加一些产生这种情况的行。

create table account_cycle_activity (
  account_id number, cycle_ctr number, activity_type_code varchar2(3), 
  activity_group_code varchar2(3), cycle_activity_amount number,
  cycle_activity_count number);
insert into account_cycle_activity values ( 1,   1, '011', 'R12', 30, 1);
insert into account_cycle_activity values ( 2,  12, '011', 'R12', 30, 1);
insert into account_cycle_activity values ( 2,   8, '011', 'R12', 30, 1);
insert into account_cycle_activity values ( 2,   8, '011', 'R12', 30, 1);
insert into account_cycle_activity values ( 2, 100, '021', 'R12', 30, 1);
insert into account_cycle_activity values ( 2,  98, '021', 'R12', 18, 1);
insert into account_cycle_activity values ( 2,  95, '021', 'R12', 30, 1);
insert into account_cycle_activity values ( 2,  92, '021', 'R12', 30, 1);

create table card_account (account_id number, cycle_ctr number);
insert into card_account values ( 1,   2 );
insert into card_account values ( 2,   2 );
insert into card_account values ( 2,  13 );
insert into card_account values ( 2,  13 );
insert into card_account values ( 2,   9 );
insert into card_account values ( 2, 101 );
insert into card_account values ( 2,  99 );
insert into card_account values ( 2,  96 );
insert into card_account values ( 2,  93 );

修改:使用count()代替lag()的修改后的版本,添加了range部分并移动了部分where条件。

with aca as (  
  select a.*, count(1) over (
        partition by account_id, activity_type_code, activity_group_code
        order by cycle_ctr range between 6 preceding and 1 preceding ) as pcc
    from account_cycle_activity a 
    where activity_type_code in ('011', '021', '007') and activity_group_code = 'R12' 
      and cycle_activity_count = 1 )
select *
  from aca join card_account ca 
      on ca.account_id = aca.account_id and ca.cycle_ctr - 1 = aca.cycle_ctr
  where pcc = 0 and cycle_activity_amount > 25