Если мой поисковый запрос не найден, добавьте в массив - PullRequest
1 голос
/ 02 августа 2020

Циклический просмотр списка терминов и поиск в базе данных для каждого термина. Есть ли способ вернуть список условий поиска, по которым не было найдено результатов в базе данных?

Это мой SELECT запрос:

SELECT x_tbl.x_str
    FROM x_tbl
    LEFT JOIN p_tbl ON p_tbl.p_id = x_tbl.p_id
    LEFT JOIN t_tbl ON t_tbl.t_id = x_tbl.t_id
    WHERE t_tbl.t = %(uw)s
    OR    t_tbl.ta = %(uw)s
    OR    %(uw)s = ANY (t_tbl.tb)
    OR    t_tbl.tc = %(uw)s
    OR    p_tbl.pa = %(uw)s
    OR    %(uw)s = ANY (p_tbl.pb)

Я хочу вернуть uw если он не находит результатов в базе данных. Возможно ли это?

1 Ответ

1 голос
/ 02 августа 2020

Я хочу вернуть 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)
   );

Основы:

Возможно, вы захотите для сохранения элементов массива в исходном порядке или даже для прикрепления порядкового номера. См .:

Кроме того, ваш исходный запрос может умножать строки - , если может быть более одной строки с правой стороны каждого соединения. См .:

...