#sql #left-join #amazon-redshift #where-clause #full-outer-join
#sql #левое соединение #amazon-redshift #where-предложение #full-outer-join
Вопрос:
У меня есть две таблицы, spend и bookings, для которых я пытаюсь выполнить полное объединение. Из-за характера таблиц (не у всех бронирований есть spend , и не у всех spend есть booking_id , а иногда присваивается неправильный booking_id), я хотел бы выполнить условный оператор в предложении join .
select bk.booking_id, bk.company_id, bk.event_id, bk.total_amount_booked, sp.spend
from
(select booking_id, company_id, event_id, booked_rate, total_amount_booked
from bookings) bk
full join
(select booking_id, company_id, event_id, normalized_spend, spend
from spend) sp
on (bk.booking_id = sp.booking_id and bk.booked_rate = sp.normalized_spend)
or (bk.company_id = sp.company_id and bk.event_id = sp.event_id);
В принципе, если booking_id совпадает, а нормализованный расход соответствует booked_rate, тогда присоединяйтесь к этому условию.
Если нет, присоединяйтесь к company_id и event_id.
Однако выполнение этого запроса возвращает
FULL JOIN is only supported with merge-joinable join conditions;
Есть ли лучший способ сделать это? Использование Redshift
Комментарии:
1. В стороне — RedShift не выполняется в PostgreSQL. Это отдельная СУБД, созданная на более раннем диалекте Postgres.
2. DataGrip говорит, что я использую PostgreSQL 8.0.2 на i686-pc-linux-gnu, скомпилированный GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.19097. Я предполагаю, что это более старая версия Postgres, но есть некоторые функции, которые вы не можете выполнить в Redshift, которые вы можете выполнить в PostgreSQL.
Ответ №1:
Это немного болезненно, но вы можете эмулировать full
соединение с помощью двух left joins
и union all
:
select bk.booking_id, bk.company_id, bk.event_id, bk.total_amount_booked, sp.spend
from bookings bk
left join spend sp
on (bk.booking_id = sp.booking_id and bk.booked_rate = sp.normalized_spend)
or (bk.company_id = sp.company_id and bk.event_id = sp.event_id)
union all
select bk.booking_id, bk.company_id, bk.event_id, bk.total_amount_booked, sp.spend
from spend sp
left join bookings bk
on (bk.booking_id = sp.booking_id and bk.booked_rate = sp.normalized_spend)
or (bk.company_id = sp.company_id and bk.event_id = sp.event_id)
where bk.booking_id is null
Ответ №2:
Возможно, используя оператор CASE, что-то вроде
...ON CASE WHEN (bk.booking_id = sp.booking_id and bk.booked_rate = sp.normalized_spend)
THEN (bk.booking_id = sp.booking_id and bk.booked_rate = sp.normalized_spend)
WHEN (bk.company_id = sp.company_id and bk.event_id = sp.event_id)
THEN (bk.company_id = sp.company_id and bk.event_id = sp.event_id)
END
Комментарии:
1. Это выдает ту же ошибку «ПОЛНОЕ ОБЪЕДИНЕНИЕ поддерживается только с условиями объединения, совместимыми с объединением»