2012-08-22 6 views
1

나는 다음과 같은 테이블이 있습니다이 쿼리를 만드는 방법은 무엇입니까?

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

나는 특정 작업이 수행되지 않은 모든 주문을 취득하고 싶습니다. 명령은 행동을 포함 할 수도 있고 포함하지 않을 수도 있습니다. 어떤 행동이없는 주문 잘 작동

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 적용되지 않은 모든 주문을 얻기 위해 싶다고 가정하면 하지만 주문에 13과 다른 조치가있는 경우 잘못된 긍정 판정을받습니다. actions 표가 포함 된 다른 조인이 누락 되었습니까? GROUP BY 또는 WHERE 조항이 있습니까?

도움을 주시면 감사하겠습니다.

+0

어떤 DBMS를 사용하고 있습니까? –

+0

MySQL, 답장을 보내 주셔서 감사합니다. – Triztian

답변

1

또한 의해 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 
+0

이 복잡해 보입니다. 흥미로운 접근. –

+0

@ JohnBingham. . . 그것은 당신이 어떻게 보느냐에 달려 있습니다. 나에게, 집합의 멤버를 필터링하기 위해 having 절을 사용하는 것은 전혀 복잡하지 않다. 사실 상관 관계가있는 하위 쿼리보다 간단합니다. –

+0

전적으로 동의합니다. 쿼리는 내가 염두에 두었지만 SQL로 표현하는 방법을 알지 못했습니다. – Triztian

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).

+0

왜 '1'값, 내가 약간의 질문을 시도하고 오랜 시간이 걸립니다, 그것은 실행을 완료하지 않은 것입니다. 약 2.3k 주문 및 5k 주문 조치가 있습니다. – Triztian

+0

'action' 열에 색인이 있습니까? 'order'는'order_actions'의 기본 키입니까? '1'은 단지'SELECT'가 비어 있지 않기 때문에,''X "'나 어떤 열'tmp.order'이 될 수 있습니다, 왜냐하면 우리는 그 sub-select의 결과에 관심이 없기 때문입니다, 'NOT EXISTS'에 대한 행을 리턴하거나 리턴하지 않습니다. –

+0

나는 색인을 만들었고 실제로'orders (id)'는 영원히 계속되는 기본 열쇠이다. 어쨌든 고마워. – Triztian

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 

이 명령은 선택한 주문에 대한 조치 번호를 반환하지 않으며, 하지만 당신은 단지 havent에 액션이있는 명령을 찾고 있다고 말했고, 여기서는 @Action으로 참조합니다.

관련 문제