2011-08-08 2 views
-1

내가이 (가)이 LEFT JOIN (UNION ALL을 제안하지 마십시오)를 사용하여 다음을 수행 할 같은 테이블는 MySQL의 조건

SELECT o.*, s.col1, s.col2 FROM order o 
    INNER JOIN user u ON o.user_id = u.id 

    IF o.date less than '2011-01-01' 
     JOIN subscribe s ON u.key = s.key 
    ELSE 
     JOIN subscribe s ON u.email = s.email 
    END IF; 

를 사용하여 가입 나는이 그러나 그것을 테스트 할 수 없습니다 다음 사용.

SELECT o.*, COALESCE(s1.col1,s2.col1) AS 
    col1, COALESCE(s1.col2, s2.col2) AS col2 
    FROM order o INNER JOIN user u ON o.user_id = u.id 
    LEFT JOIN subscribe s1 ON 
    (u.key LIKE (CASE o.date >= '2011-01-01 00:00:00' 
         WHEN TRUE THEN s1.key ELSE NULL END)) 
     LEFT JOIN subscribe s2 ON (u.email LIKE (CASE o.date < 
     '2011-01-01 00:00:00' WHEN TRUE THEN s.email 
     ELSE NULL END)); 

내가 잘못하면 저를 시정하십시오.

감사합니다. 당신은 두 번 가입 할 필요가 없습니다

+0

코드를 테스트 할 수없는 원인은 무엇입니까? –

+0

테스트 환경 설정이 없기 때문에 – arun

답변

5

은 다음과 같이 그것을 :

SELECT o.*, s.col1, s.col2 
    FROM order o INNER JOIN user u ON o.user_id = u.id 
    LEFT JOIN subscribe s ON((o.date < '2011-01-01' AND u.key = s.key) OR 
          (o.date >= '2011-01-01' AND u.email = s.email)) 

그리고 여기 당신이 subscribe.keysubscribe.email에 인덱스가있는 경우 전체 테이블을 스캔하지 않을 해결책은 다음과 같습니다

SELECT * FROM 
(
    (SELECT 0 AS mode, o.date AS odate, o.*, s.col1, s.col2 
     FROM order o INNER JOIN user u ON o.user_id = u.id 
     LEFT JOIN subscribe s ON(u.key = s.key)) 
    UNION 
    (SELECT 1 AS mode, o.date AS odate, o.*, s.col1, s.col2 
     FROM order o INNER JOIN user u ON o.user_id = u.id 
     LEFT JOIN subscribe s ON(u.email = s.email)) 
) 
WHERE (odate < '2011-01-01' AND mode = 0) OR 
     (odate >= '2011-01-01' AND mode = 1) 
+0

+1 쉽고 간단합니다. –

+0

조건부 조인 때문에 전체 테이블 스캔을 수행하기 때문에 subselects를 사용하여 쿼리를 어떻게 분할 할 수 있습니까? – arun

+0

@arun 업데이트를 확인하십시오. – nobody