MySQL передает родительское поле в подзапрос без использования JOINS - PullRequest
0 голосов
/ 02 мая 2019

Мне нужно передать поле в подзапрос вместо использования JOIN, но большинство примеров в Интернете показывают только, как это сделать с помощью объединений.

Сценарий следующий:

У меня естьтаблица счетов в системе.Каждая учетная запись может выполнять задачи, которые могут потерпеть неудачу.Я хочу получить список учетных записей с настраиваемым столбцом «статус», который равен -1, если последние две задачи не выполнены.

Например,

SELECT Account.id, (

    CASE WHEN (

       (SELECT COUNT(*) FROM (

           SELECT id, status FROM Task
           WHERE Task.AccountId = Account.id // <-- Cannot access Account.id here
           HAVING status < 0 // <-- only select failed tasks
           ORDER BY id DESC
           LIMIT 2
       ) as t1)

    ) < 2 THEN 1 ELSE -1 END

) as `status` FROM Account;

Вычисление статуса для каждой задачи являетсятяжелый запрос (не показан выше), поэтому я хочу вычислять состояние только для задач, принадлежащих запрашиваемым учетным записям.

Я пытался использовать пользовательские переменные, заменив Account.id на @AccountId, но яне думаю, что их можно использовать в подобном подзапросе.

Я не могу использовать JOIN в основной таблице Account, потому что я использую sequelize.Однако я могу использовать JOIN в подзапросе, если это поможет.

Ответы [ 2 ]

1 голос
/ 02 мая 2019

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

select a.*,
       (case when (select t.status
                   from task t
                   where t.AccountId = a.id
                   order by t.id desc
                   limit 1
                  ) = -1 and
                  (select t.status
                   from task t
                   where t.AccountId = a.id
                   order by t.id desc
                   limit 1 offset 1
                  ) = -1
             then 1 else -1
         end)                  
from accounts a;

Для производительности вам нужен индекс на task(accountid, id, status).

1 голос
/ 02 мая 2019

Это единственное решение, которое я могу придумать (хотя возможно использовать хотя бы 1002 *).Работает для последних двух строк:

SELECT Account.id, (
    SELECT status
    FROM Task
    WHERE Task.AccountId = Account.id
    ORDER BY Task.Id DESC
    LIMIT 0, 1
) + (
    SELECT status
    FROM Task
    WHERE Task.AccountId = Account.id
    ORDER BY Task.Id DESC
    LIMIT 1, 1
) AS sum_of_last_two
FROM Account

Результатом будет -2, -1 или 0 и т. Д., Которые могут быть проверены внутри CASE.Возможно, вы захотите обернуть каждый подзапрос внутри COALESCE((...), 0)

...