SQL查询连接四个表

时间:2018-02-06 13:37:01

标签: sql database join

原始查询正在加入客户表和合约表以及额外服务历史记录,这一切都有效。

但是我在添加第4个表时遇到了问题,这个表应该应用其他一些标准。

当前工作查询(无需更改):

select b.*
from SubscribersFIN b

inner join (select Id, Account_Number, ContractNumber, BackendId
from Contract) e on b.c_id='FI_' + e.Account_Number

left join (select Contract
from Extra_Service_History
where Service_Name='debit_plan') d on e.Id=d.Contract

where COUNTRY='fi' 
and NO_SMS = 0
and d.Contract is null

目标是过滤来自大查询的集合,该集合仅记录在发票中显示的付费状态。

right join (select Contract 
from Invoice
where Status = 'PAID') i on e.Id=i.Contract

这个似乎没有做到这一点,所以我无法弄清楚这里需要什么样的连接类型或逻辑。

3 个答案:

答案 0 :(得分:1)

不要混合使用LEFT和RIGHT联接,只需将其作为INNER联接放在查询的最高位置:

select b.*
from SubscribersFIN b

inner join (select Id, Account_Number, ContractNumber, BackendId
from Contract) e on b.c_id='FI_' + e.Account_Number

inner join (select Contract 
from Invoice
where Status = 'PAID') i on e.Id=i.Contract

left join (select Contract
from Extra_Service_History
where Service_Name='debit_plan') d on e.Id=d.Contract

where COUNTRY='fi' 
and NO_SMS = 0
and d.Contract is null

答案 1 :(得分:1)

根据我的理解,我只是重新安排了查询。试试这个。如果where条件列来自任何LEFT JOIN表,请在on子句中加入它们。

select b.* from SubscribersFIN b
inner join Contract e  on b.c_id='FI_' + e.Account_Number
left join  Extra_Service_History d on e.Id=d.Contract and d.Service_Name='debit_plan' and d.Contract is null
left join invoice i on e.Id=i.Contract and i.Status = 'PAID'
where COUNTRY='fi'  and NO_SMS = 0

答案 2 :(得分:1)

您有几个选择:

  1. INNER JOIN
  2. 根据外部联接的特定类型,它们返回未找到匹配项的行(联接的左侧,右侧或两侧)。根据您的描述,这不是您想要的。只需使用:

    inner join (select Contract 
    from Invoice
    where Status = 'PAID') i on e.Id=i.Contract
    

    在FROM子句中发生这种情况无关紧要;如果这两个表之间的连接是INNER。查询引擎可以自由重新排列以提高性能,前提是它不会更改语义。 (但我个人认为将INNER JOIN放在最顶端更为温和。)

    1. IN过滤器
    2. 您所描述的是过滤器。

        

      目标是过滤来自大型查询的集合,该集合仅记录在“发票”中显示的付费状态。

      因此,将其作为WHERE子句中的过滤器实现更为清晰。 E.g。

      where e.Id in (select  Contract 
                     from    Invoice
                     where   Status = 'PAID')
        and ...
      
      1. EXISTS过滤器
      2. 与上述类似,但改为使用EXISTS子查询。

        where exists (select  *
                      from    Invoice i
                      where   Status = 'PAID'
                          and i.Contract = e.Id)
          and ...