#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
условии не сделает его менее пустым.