SQL оставил соединение с предложением где на правой таблице - PullRequest
1 голос
/ 12 апреля 2019

Мне нужно запросить клиента в базе данных по нескольким критериям.

В моей базе данных у меня есть 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 Ответ

2 голосов
/ 12 апреля 2019

Есть несколько частей, объясняющих это:

  • Прежде всего, вы делаете левое соединение с этими таблицами, поэтому наличие или отсутствие данных в таблицах контактов / адресов не уменьшитчисло записей в выходных данных.
  • Если вы ожидали ничего не получать из-за примененных фильтров, вы должны знать, что поведение фильтрации таблицы в условии соединения не совпадает с фильтрацией таблицы вусловие where:
    • Фильтр применяется в объединении: фильтр выполняется перед продолжением объединения таблиц
    • Фильтр применяется в 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 '%%' всегда, вам нужно будет преобразовать нули в некоторую строку, например, в пустую строку where isnull(c.valeur,'') like '%%', и это тоже должно работать.Надеюсь, это поможет, вы можете проверить это отсюда

...