2011-08-08 58 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

我們是否可以使用子查詢以某種方式拆分查詢,因爲它正在進行全表掃描,因爲條件連接? – arun

+0

@arun查看更新。 – nobody