How to FULL OUTER JOIN multiple tables in MySQL

Шыназ Алиш picture Шыназ Алиш · May 28, 2015 · Viewed 14.4k times · Source

I need to FULL OUTER JOIN multiple tables. I know how to FULL OUTER JOIN two tables from here. But I have several tables, and I can't apply it over them. How can I achieve it?
My SQL code, below:

INSERT INTO table
(
  customer_id
 ,g01
 ,g02
 ,g03
 ,has_card
 ,activity
  )
  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  LEFT JOIN s_category sc
  ON sc.customer_id = sgd.customer_id
    UNION
  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  RIGHT JOIN s_category sc
  ON sc.customer_id = sgd.customer_id

    UNION

  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  LEFT JOIN s_activity a
  ON a.customer_id = sgd.customer_id
    UNION
  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  RIGHT JOIN s_activity a
  ON a.customer_id = sgd.customer_id

Also I tried this query:

INSERT INTO reportls.table
(
  customer_id
 ,g01
 ,g02
 ,g03
 ,has_card
 ,activity
  )
  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  LEFT JOIN s_category sc
  ON sc.customer_id = sgd.customer_id
  LEFT JOIN s_activity a
  ON sc.customer_id = sgd.customer_id

    UNION

  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  LEFT JOIN s_category sc
  ON sc.customer_id = sgd.customer_id
  RIGHT JOIN s_activity a
  ON a.customer_id = sgd.customer_id

    UNION

  SELECT sgd.customer_id, sgd.g01,sgd.g02,sgd.g03,sc.value, a.activity
  FROM s_geo_data sgd
  RIGHT JOIN s_category sc
  ON sc.customer_id = sgd.customer_id
  LEFT JOIN s_activity a
  ON a.customer_id = sgd.customer_id

Last query executes very long time, I need faster query.

Answer

shA.t picture shA.t · May 28, 2015

I think to have a FULL OUTER JOIN over 3 tables, you need to do it like this:

SELECT t1.value, t2.value, t3.value
FROM t1 LEFT JOIN t2 ON t1.value = t2.value
        LEFT JOIN t3 ON t1.value = t3.value
UNION ALL
SELECT t1.value, t2.value, t3.value
FROM t2 LEFT JOIN t1 ON t1.value = t2.value
        LEFT JOIN t3 ON t2.value = t3.value
WHERE t1.value IS NULL
UNION ALL
SELECT t1.value, t2.value, t3.value
FROM t3 LEFT JOIN t1 ON t1.value = t3.value
        LEFT JOIN t2 ON t2.value = t3.value
WHERE t1.value IS NULL AND t2.value IS NULL

As an alternative for this:

SELECT t1.value, t2.value, t3.value
FROM t1 FULL OUTER JOIN t2 ON t1.value = t2.value
        FULL OUTER JOIN t3 ON t1.value = t3.value

I suggest you to create some temporary tables like t1, t2 and t3 for storing results of your queries, then use above query over those.