使用自联接查看我的查询

时间:2014-02-20 14:51:21

标签: sql oracle view self-join

有更优雅的方式来定义以下视图吗?我需要将表格缩减为每个公司类型10 联系人

CREATE VIEW COMPANY_LAST_ACQ_CONTACT
as
select 
ci.id, ci.company_id, ci.be_user_id, ci.created_datetime, ci.text
from
(select max(id) as id, company_id
from crm_contact
WHERE crm_contact_reason_id = 10
group by company_id
) co
join crm_contact ci on co.company_id=ci.company_id
;

如果我对be_user_id,created_datetime,text不感兴趣,它会简化为:

CREATE VIEW COMPANY_LAST_ACQ_CONTACT
as
select max(id) as id, company_id
from crm_contact
WHERE crm_contact_reason_id = 10
group by company_id;

第一个视图似乎一切都很好,只要我不加入特定的复杂选择 - 查询然后挂起/永久运行(至少超过20分钟)。如果我加入第二个视图版本,则不会发生这种情况 - 这次查询会立即返回结果。我甚至尝试在复杂的select中再次使用crm_contact加入第二个视图以获取三列(be_user_id,created_datetime,text)并且它运行得很快。

1 个答案:

答案 0 :(得分:1)

您仍然需要子查询,但分析函数更优雅:

CREATE VIEW COMPANY_LAST_ACQ_CONTACT as
    select id, company_id, be_user_id, created_datetime, text
    from (select ci.id, ci.company_id, ci.be_user_id, ci.created_datetime, ci.text,
                 max(id) over (partition by company_id) as maxid
          from crm_contact
         ) c
    where id = maxid;

编写查询的另一种有效方法 - 如果您在company_id, id上有索引,则使用not exists

select ci.id, ci.company_id, ci.be_user_id, ci.created_datetime, ci.text
from crm_contact c
where not exists (select 1` from crm_contact cc on c.company_id = cc.company_id and cc.id > id);