Способ сделать запрос с внутренним объединением, для обновления X пропустить заблокирован, порядок и лимит - PullRequest
0 голосов
/ 14 февраля 2019

Мне нужно получить N записей таблицы X, но мне нужно отфильтровать эти записи, используя INNER JOIN, и заранее упорядочить их по объединенным записям.

Пример того, что я пытался сделать(может быть не точным на 100%, так как я использую SQLAlchemy):

SELECT X.id
FROM X
   INNER JOIN Y ON X.id = Y.other_id
WHERE Y.condition_one
ORDER BY Y.condition_two
LIMIT 10
FOR UPDATE OF X SKIP LOCKED;

Когда я делаю это, я получаю менее 10 различных id с (возможно, потому что объединенные строки ограничены)однако я не могу выполнить DISTINCT с FOR UPDATE.Я думаю, что не могу использовать подзапрос из-за FOR UPDATE.

Что мне делать?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

У меня были проблемы с одновременным использованием DISTINCT и ORDER BY.

Соединение LATERAL должно было работать теоретически, но, работая над реализацией, я нашел другой подход:

SELECT X.id
FROM X
   JOIN (SELECT X.id, MIN(Y.condition_two) AS ordering
         FROM X
            INNER JOIN Y ON X.id = Y.other_id
         WHERE Y.condition_one) AS sub_x
      ON X.id = sub_x.id
ORDER BY ASC(sub_x.ordering)
LIMIT 10
FOR UPDATE OF X SKIP LOCKED;

Если бы я хотел заказать с помощью DESC, мне пришлось бы изменить MIN на MAX.

0 голосов
/ 14 февраля 2019

Вы можете использовать боковое соединение:

SELECT X.id
FROM X
   CROSS JOIN LATERAL (
      SELECT Y.condition_two
      FROM Y
      WHERE X.id = Y.other_id
        AND Y.condition_one
      ORDER BY Y.condition_two
      LIMIT 1) AS first_y
ORDER BY first_y.condition_two
LIMIT 10
FOR UPDATE OF X SKIP LOCKED;

Или (проще) использовать подвыбор с DISTINCT:

SELECT X.id
FROM X
   JOIN (SELECT DISTINCT X.id
         FROM X
            INNER JOIN Y ON X.id = Y.other_id
         WHERE Y.condition_one
         ORDER BY Y.condition_two
         LIMIT 10) AS sub_x
      ON X.id = sub_x.id
FOR UPDATE OF X SKIP LOCKED;
...