如何创建此查询?

时间:2012-08-22 00:22:30

标签: mysql sql join

我有以下表格:

actions(id, name)
orders(refno, po)
order_actions(order, action)

我想获得尚未执行特定操作的所有订单。订单可能包含或不包含任何操作。

假设我想获得尚未应用行动13的所有订单,到目前为止,我有类似的内容:

SELECT o.po, oa.action, 
    FROM orders AS `o`
    LEFT JOIN order_actions AS `oa` ON o.refno = oa.order
WHERE oa.action <> 13

这适用于没有操作的订单,但如果订单的操作不同于13我得到误报,我错过了另一个涉及actions表的连接可能是{{ 1}}对于po或额外的GROUP BY子句?

感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

SELECT o.po, oa.action
FROM orders AS `o`
     LEFT JOIN order_actions AS `oa` ON o.refno = oa.order
WHERE NOT EXISTS (
  SELECT 1 
  FROM order_actions tmp 
  WHERE oa.order = tmp.order 
    AND tmp.action = '13'
)

DEMO (sqlfiddle)。

答案 1 :(得分:1)

您还可以使用group by和having子句解决此问题:

SELECT o.refno, o.po
FROM orders AS `o` LEFT JOIN
     order_actions `oa`
     ON o.refno = oa.order
group by o.refno, o.po
having max(case when oa.action = 13 then 1 else 0 end) = 0

如果您想跟踪此类订单上的所有操作,可以使用group_concat:

SELECT o.refno, o.po,
       group_concat(cast(ao.action) separator ', ') as AllOtherActions
FROM orders AS `o` LEFT JOIN
     order_actions `oa`
     ON o.refno = oa.order
group by o.refno, o.po
having max(case when oa.action = 13 then 1 else 0 end) = 0

答案 2 :(得分:0)

另一种选择是:

select o.po
from orders as 'o'
    left join (
        select order from order_actions where [action] = @Action
        ) AS `oa` on o.refno = oa.order
where oa.order is null

这不会返回您选择的订单的操作号码,但您已经声明您只是在寻找没有操作的订单,我在这里将其称为@Action

相关问题