MySQL不使用JOINS将父字段传递给子查询

时间:2019-05-02 10:21:19

标签: mysql sql subquery sequelize.js

我需要将字段传递给子查询,而不是使用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;

每个任务的计算状态是一个繁琐的查询(上面未显示),因此我只想计算属于所查询帐户的任务的状态。

我尝试使用用户变量,用@AccountId替换Account.id,但我认为没有人可以在这样的子查询中使用它们。

我无法在主帐户表上使用JOIN,因为我正在使用续集。但是,如果有帮助,我可以在子查询中使用JOIN。

2 个答案:

答案 0 :(得分:1)

这是我能想到的唯一解决方案(尽管 可以使用联接)。适用于最后两行:

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)

答案 1 :(得分:1)

对于您的特定问题,您可以针对要检查的每种状态使用单独的查询来表示:

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)上建立索引。