или где запрос не возвращает результаты, в то время как отдельные запросы возвращают результаты

#sql #postgresql #join

#sql #postgresql #Присоединиться

Вопрос:

этот SQL-запрос возвращает некоторые результаты:

 select
  "titres".*
from
  "titres"
  inner join "titres_titulaires" as "titulaires_join" on "titulaires_join"."titre_etape_id" = "titres"."titulaires_titre_etape_id"
  inner join "entreprises" as "titulaires" on "titulaires_join"."entreprise_id" = "titulaires"."id"
where
  ("titulaires"."nom" like '%sma%')
  

Я ожидаю, что этот запрос вернет по крайней мере те же результаты:

 select
  "titres".*
from
  "titres"
  inner join "titres_titulaires" as "titulaires_join" on "titulaires_join"."titre_etape_id" = "titres"."titulaires_titre_etape_id"
  inner join "entreprises" as "titulaires" on "titulaires_join"."entreprise_id" = "titulaires"."id"
  inner join "titres_amodiataires" as "amodiataires_join" on "amodiataires_join"."titre_etape_id" = "titres"."amodiataires_titre_etape_id"
  inner join "entreprises" as "amodiataires" on "amodiataires_join"."entreprise_id" = "amodiataires"."id"
where
  (
    "titulaires"."nom" like '%sma%'
    or "amodiataires"."nom" like '%sma%'
  )
  

но он возвращает пустой массив.

что я здесь делаю не так?

Комментарии:

1. Условия объединения не совпадают в новых таблицах.

2. какие условия?

3. измените все ваши ВНУТРЕННИЕ соединения на ЛЕВОЕ соединение, и это сработает. Проблема в том, что для титров, которые вы ищете, ни у одного из них нет КАК заголовка, так и заменителя, и, таким образом, все результаты отфильтровываются ВНУТРЕННИМИ объединениями. Ваш запрос легче понять для говорящего по-французски 😉

4. вы можете сохранить приведенный ниже ответ, ТОЛЬКО если для ВСЕХ титров у вас ВСЕГДА есть titulaire и, ВОЗМОЖНО, amanditaire. Если для некоторых титров у вас нет заголовка, ваши результаты будут отфильтрованы.

5. должен ли я изменить ВСЕ соединения… вы говорите нам. Правильный ответ — это ваш желаемый результат.

Ответ №1:

используйте левое соединение вместо внутреннего соединения для последних 2 соединений

 select
  "titres".*
from
  "titres"
  inner join "titres_titulaires" as "titulaires_join" on "titulaires_join"."titre_etape_id" = "titres"."titulaires_titre_etape_id"
  inner join "entreprises" as "titulaires" on "titulaires_join"."entreprise_id" = "titulaires"."id"
  left join "titres_amodiataires" as "amodiataires_join" on "amodiataires_join"."titre_etape_id" = "titres"."amodiataires_titre_etape_id"
  left join "entreprises" as "amodiataires" on "amodiataires_join"."entreprise_id" = "amodiataires"."id"
where
  (
    "titulaires"."nom" like '%sma%'
    or "amodiataires"."nom" like '%sma%'
  )
  

Комментарии:

1. Хотя ваш ответ может быть правильным, было бы неплохо объяснить ему, ПОЧЕМУ.

2. @ThomasG не видя пример вывода, сложно сказать, что это не сработает и изменится для всех соединений, так что это зависит, но для проблемы, в которой op сказал, что 1-й запрос возвращает что-то, но 2-й не в этом случае это сработает

Ответ №2:

Я попытаюсь объяснить, почему это может произойти.

Давайте представим, что в titres_amodiataires нет ни одной строки, которая соответствовала бы строке в titres , т. Е. Никакие две строки не удовлетворяют titres_amodiataires.titre_etape_id = titres.amodiataires_titre_etape_id .

Тогда результат JOIN s будет пустым, и применение дополнительных фильтров в WHERE условии не сделает его менее пустым.