SQL左连接带子句的位置在右表上

时间:2019-04-12 12:57:46

标签: sql postgresql left-join

我需要在具有多个条件的数据库上请求客户。

在我的数据库中,我有3个表

客户:

id
nom
prenom
...

联系方式:

id
valeur
customer_id

根据我的要求,我有:valeur

这是请求:

select client0_.id as id1_6_
from client client0_ 
inner join entite entite1_ on client0_.entite_id=entite1_.id 
left outer join client_adresse clientadre2_ on     (clientadre2_.client_id=client0_.id) 
left outer join client_contact clientcont3_ on (clientcont3_.client_id=client0_.id) 
where (entite1_.numero_licence in ('ZB230EC')) 
and (upper(client0_.nom) like ('%'||upper('')||'%')) 
and (client0_.prenom is null or upper(client0_.prenom) like ('%'||upper('')||'%')) 
and (clientcont3_.valeur like ('%'||'@mail'||'%')) 
and (client0_.date_creation_sys is null or client0_.date_creation_sys>='2017-01-01') 
and (client0_.date_modification_sys is null or client0_.date_modification_sys>='2017-01-01') 
and (client0_.date_suppression is null or client0_.date_suppression>='9999-12-12')

此请求还给我未联系过的客户,我的请求又请联系“ valeur”的客户包含“ @mail”

样本数据

客户

id  | nom     | prenom 
375 | aurelie |  lilie
389 | t(      | 

联系方式

id    |  valeur             | customer_id
2740  |  aurelie@mail.com   |  375
2739  |  06 06 06 06 06     |  375

如果我通过搜索启动请求:

    contact.valeur like '%@mail%'
and customer.nom like '%%'

我的结果还可以

但是:

    contact.valeur like '%%'
and customer.nom like '%t(%'

我有空结果

你能帮我吗?

1 个答案:

答案 0 :(得分:2)

有一些解释这一点的东西:

  • 首先,您正在对这些表进行左连接,因此,contact / address表中是否包含数据不会减少输出中的记录数。
  • 如果由于应用了过滤器而等待接收任何内容,则必须知道在联接条件下过滤表的行为与在where条件下过滤表的行为不同:
    • 在联接中应用了过滤器:过滤器是在继续联接表之前完成的
    • 在以下位置应用过滤器:过滤器是在连接表后完成的

因此,如果您一无所获,只需将过滤器从“连接部分”移至“位置部分”即可。

修改后的答案

只解释我的评论...

with customer as (
  select 375 as id, 'aurelie' as nom, 'lilie' as prenom union all
  select 389, 't(', null
),
contact as (
  select 2740 as id, 'aurelie@mail.com' as valeur, 375 customer_id union all
  select 2739, '06 06 06 06 06', 375
)
select *
from customer cs
  left join contact c
    on cs.id=c.customer_id
where c.valeur like '%%'
  and cs.nom like '%t(%'

这什么都不返回,因为您正在将NULL与like '%%'

进行比较

如果将此where c.valeur like '%%'替换为where c.valeur is null,则会得到您想要的记录。 如果您想始终继续使用此where c.valeur like '%%',则需要将null转换为某个字符串,例如空字符串where isnull(c.valeur,'') like '%%',它也应该起作用。 希望对您有所帮助,您可以对其进行测试from here