Я хочу вернуть uw
, если он не находит результатов в базе данных.
Для одного поискового запроса
Два LEFT [OUTER] JOIN
между x_tbl
, p_tbl
и t_tbl
сами по себе не удаляют никакие строки. Дважды NOT EXISTS
возвращает список условий поиска, по которым ничего не найдено:
SELECT %(uw)s -- old-style Python placeholder
WHERE NOT EXISTS (
SELECT FROM p_tbl
WHERE pa = %(uw)s
OR %(uw)s = ANY (p.pb)
)
AND NOT EXISTS (
SELECT FROM t_tbl
WHERE %(uw)s IN (t, ta, tc)
OR %(uw)s = ANY (tb)
);
Если , могут быть сироты в t_tbl
и / или p_tbl
(не связаны в любую строку в x_tbl
), набор может быть больше, и запрос станет более дорогим:
SELECT %(uw)s -- old-style Python placeholder
WHERE NOT EXISTS NOT EXISTS (
SELECT FROM x_tbl JOIN p_tbl p USING (p_id)
WHERE p.pa = %(uw)s
OR %(uw)s = ANY (p.pb)
)
AND (
SELECT FROM x_tbl JOIN t_tbl t USING (t_id)
WHERE %(uw)s IN (t.t, t.ta, t.tc)
OR %(uw)s = ANY (t.tb)
);
Это касается одного поискового запроса за один раз, как в исходном запросе. Вы упомянули список . Выполнение одного запроса для всех из них может быть (намного) дешевле ...
Один запрос, чтобы управлять ими всеми
Передать список как массив (Postgres литерал массива) - что может требуется явное приведение (::text[]
) - unnest()
и присоединить те же условия WHERE
, как указано выше:
SELECT uw
FROM unnest(%(my_list_as_array)s::text[]) q(uw)
WHERE NOT EXISTS (
SELECT FROM p_tbl
WHERE pa = q.uw
OR q.uw = ANY (p.pb)
)
AND NOT EXISTS (
SELECT FROM t_tbl
WHERE q.uw IN (t, ta, tc)
OR q.uw = ANY (tb)
);
Или, включая соединение с tbl_x
, то же как указано выше:
SELECT uw
FROM unnest(%(my_list_as_array)s::text[]) q(uw)
WHERE NOT EXISTS (
SELECT FROM x_tbl JOIN p_tbl p USING (p_id)
WHERE p.pa = q.uw
OR q.uw = ANY (p.pb)
)
AND NOT EXISTS (
SELECT FROM x_tbl JOIN t_tbl t USING (t_id)
WHERE q.uw IN (t.t, t.ta, t.tc)
OR q.uw = ANY (t.tb)
);
Основы:
Возможно, вы захотите для сохранения элементов массива в исходном порядке или даже для прикрепления порядкового номера. См .:
Кроме того, ваш исходный запрос может умножать строки - , если может быть более одной строки с правой стороны каждого соединения. См .: