MySQL условное соединение с использованием той же таблицы - PullRequest
0 голосов
/ 08 августа 2011

Я хочу сделать следующее, используя LEFT JOIN (пожалуйста, не предлагайте UNION ALL)

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

Пожалуйста, поправьте меня, если я ошибаюсь.

Спасибо.

1 Ответ

5 голосов
/ 08 августа 2011

Вам не нужно присоединяться дважды, сделайте это так:

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.keyи subscribe.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 )
...