我需要将字段传递给子查询,而不是使用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。
答案 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)
上建立索引。