原始查询正在加入客户表和合约表以及额外服务历史记录,这一切都有效。
但是我在添加第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
这个似乎没有做到这一点,所以我无法弄清楚这里需要什么样的连接类型或逻辑。
答案 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)
您有几个选择:
根据外部联接的特定类型,它们返回未找到匹配项的行(联接的左侧,右侧或两侧)。根据您的描述,这不是您想要的。只需使用:
inner join (select Contract
from Invoice
where Status = 'PAID') i on e.Id=i.Contract
在FROM子句中发生这种情况无关紧要;如果这两个表之间的连接是INNER。查询引擎可以自由重新排列以提高性能,前提是它不会更改语义。 (但我个人认为将INNER JOIN放在最顶端更为温和。)
您所描述的是过滤器。
目标是过滤来自大型查询的集合,该集合仅记录在“发票”中显示的付费状态。
因此,将其作为WHERE子句中的过滤器实现更为清晰。 E.g。
where e.Id in (select Contract
from Invoice
where Status = 'PAID')
and ...
与上述类似,但改为使用EXISTS子查询。
where exists (select *
from Invoice i
where Status = 'PAID'
and i.Contract = e.Id)
and ...