Search code examples
mysqlsqlsumpivotfull-outer-join

FULL OUTER JOIN with union subqueries


I am trying to create an output with a similar behaviour to FULL OUTER JOIN, with UNION in mysql

The queires I am trying to combine are the same with different time frame parameteres

EXAMPLE:

Select * from (
SELECT GGPORTAL as portal, sum(oa.GGAMOUNT) as amount FROM orders as o 
        left orderarticles as oa on o.GGAUFTRAGSNR = oa.GGAUFTRAGSNR 
        where o.GGDATE >= '2020-01-01' and o.GGDATE <= '2020-12-31' 
        group by GGPORTAL
        ) as t1
        LEFT JOIN t2 ON t1.GGPORTAL = t2.GGPORTAL
UNION 
Select * from (
SELECT GGPORTAL as portal, sum(oa.GGAMOUNT) as amount2 FROM orders as o 
        left join orderarticles as oa on o.GGAUFTRAGSNR = oa.GGAUFTRAGSNR 
        where o.GGDATE >= '2019-01-01' and o.GGDATE <= '2019-12-31' 
        group by GGPORTAL
        ) as t2
        RIGHT JOIN t1 ON t1.GGPORTAL = t2.GGPORTAL
        WHERE t1.GGPORTAL IS NULL

ERROR:

Table 'server.t2' doesn't exist

Single subqueries:

| Portal | Amount    |
|--------|-----------|
|    3   |       250 |
|    4   |       300 |
|    8   |       400 |
|    9   |       500 |
|   10   |       600 |
| Portal | Amount    |
|--------|-----------|
|    1   |       250 |
|    3   |       200 |
|    4   |       350 |
|    8   |       450 |
|    9   |       550 |

Desired Outcome:

| Portal | Amount    | Amount2   |
|--------|-----------|-----------|
|    1   |       NULL|       250 |
|    3   |       250 |       200 |
|    4   |       300 |       350 |
|    8   |       400 |       450 |
|    9   |       500 |       550 |
|   10   |       600 |       NULL|

Question: What is the right syntax? Would there be better alternatives in PHP backend to combine the outputs of these queries?


Solution

  • I just don't see the point for union all here. Both queries are the same, only the date filter changes. So, use conditional aggregation:

    slect ggportal as portal, 
        sum(case when o.ggdate >= '2020-01-01' and o.ggdate < '2021-01-01' then oa.ggamount else 0 end) as amount_2020,
        sum(case when o.ggdate >= '2019-01-01' and o.ggdate < '2020-01-01' then oa.ggamount else 0 end) as amount_2020
    from orders as o 
    left orderarticles as oa on o.ggauftragsnr = oa.ggauftragsnr 
    where o.ggdate >= '2019-01-01' and o.ggdate < '2021-01-01' 
    group by ggportal