MySQL: Union of a Left Join with a Right Join
select a.id, t1.column_1, t2.column_2
from (
select id from t1
union
select id from t2
) a
left outer join t1 on a.id = t1.id
left outer join t2 on a.id = t2.id
MySQL UNION ALL with LEFT JOIN
So finally got there with the below, appreciate the direction halfer
SELECT
comments.*, users.company, users.contact_person, users.email
FROM
comments
LEFT JOIN users ON users.user_id = comments.user_id
WHERE
comment_id = %s
UNION ALL
SELECT activity.*, users.company, users.contact_person, users.email
FROM
activity
LEFT JOIN users ON users.user_id = activity.user_id
WHERE
comment_id = %s
ORDER BY
timestamp ASC
MySQL Left Join Right Join union returns incorrect data
You do the joins on workoutDate = weighInDate
. This gives you combinations of unrelated rows, which remain in the result set, even with unrelated user names.
To fix this, you must join on both dates and usernames, e.g.
LEFT JOIN sprint AS metric ON weight.weighInDate = metric.workoutDate
and weight.username = metric.username
similarly on right join, of course.
Added to the answer because it helps illustrate the cause of the problem. The @OlafDietsche has the correct solution. I just wanted you to see where the actual wrong data came from.
To show you the problem with your join this record:
| testuser | 2016-10-17 | 3.40
is joining to this record
| jdoe | 2016-10-17 | 160 |
because you only joined on date.
Order by left outer join union right outer join
(
SELECT *
FROM groups
LEFT OUTER JOIN group_questions
ON groups.id = group_questions.group_id
WHERE group_questions.group_id = 1
)
UNION
(
SELECT *
FROM groups
RIGHT OUTER JOIN group_questions
ON groups.id = group_questions.group_id
WHERE group_questions.group_id = 1
)
ORDER BY id DESC
You must sort combined rowset after UNION. And you must refer to the column name of combined rowset (which now does not refer to any source table of any separate subquery).
In this particular case the parenthesis wrapped separate subqueries are formally excess and may be removed. But I recommend to use them always - this removes possible ambiguity.
How to use join and union for sub queries in mysql
You need to make a couple of changes in order for this query to work:
- Wrap inner
SELECT
queries into anotherSELECT *
query to makeJOIN
work, e.g.() SP LEFT JOIN () SP
is not a valid syntax. Instead, useSELECT * FROM (..) SP JOIN (..) FP
- Remove
SP.*
from outerSELECT
asSP
andFP
are only visible to inner queries, useSELECT *
instead - Remove
WHERE SP.Service=FP.Service
from outerWHERE
clause as again,SP
andFP
won't be visible.
The below query should work:
SELECT *
FROM (
(
SELECT * FROM
(SELECT Service, SUM(Processed) as Second_Period, COUNT(Processed) as TRX_SP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-07 00:00:00' and '2017-05-14 00:00:00'
GROUP BY Service) SP
RIGHT JOIN
(SELECT Service, SUM(Processed) as First_Period, COUNT(Processed) as TRX_FP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-01 00:00:00' and '2017-05-06 00:00:00'
GROUP BY Service) FP USING (Service))
UNION ALL
(
SELECT * FROM
(SELECT Service, SUM(Processed) as Second_Period, COUNT(Processed) as TRX_SP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-07 00:00:00' and '2017-05-14 00:00:00'
GROUP BY Service) SP
LEFT OUTER JOIN
(SELECT Service, SUM(Processed) as First_Period, COUNT(Processed) as TRX_FP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-01 00:00:00' and '2017-05-06 00:00:00'
GROUP BY Service) FP USING (Service) )) as tbl2
GROUP BY Service
Order BY Service
update
You can't use function in USING
clause, so you need to alias that column and use the alias in USING
, e.g.:
SELECT *
FROM (
(
SELECT * FROM
(SELECT DAYNAME(Dataime) as 'day', SUM(Processed) as Second_Period, COUNT(Processed) as TRX_SP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-07 00:00:00' and '2017-05-14 00:00:00'
GROUP BY DAYNAME(Dataime)) SP
RIGHT JOIN
(SELECT DAYNAME(Dataime) as 'day', SUM(Processed) as First_Period, COUNT(Processed) as TRX_FP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-01 00:00:00' and '2017-05-06 00:00:00'
GROUP BY DAYNAME(Dataime)) FP USING(`day`))
UNION ALL
(
SELECT * FROM
(SELECT DAYNAME(Dataime) as `day`, SUM(Processed) as Second_Period, COUNT(Processed) as TRX_SP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-07 00:00:00' and '2017-05-14 00:00:00'
GROUP BY DAYNAME(Dataime)) SP
LEFT OUTER JOIN
(SELECT DAYNAME(Dataime) as `day`, SUM(Processed) as First_Period, COUNT(Processed) as TRX_FP
FROM pay
WHERE Status1='Processed' AND Dataime BETWEEN '2017-05-01 00:00:00' and '2017-05-06 00:00:00'
GROUP BY DAYNAME(Dataime)) FP USING (`day`) )) as tbl2
GROUP BY `day`
Order BY `day`
Combining Left & Right Join in mysql query
The only you can do that is by using UNION
. MySQL doesn't support FULL JOIN
just like in MSSQL.
SELECT *
FROM tbl1 t1
LEFT JOIN tbl2 t2
ON t1.col = t2.col
UNION
SELECT *
FROM tbl1 t1
RIGHT JOIN tbl2 t2
ON t1.col>= t2.<col
SEE HERE: Simulating FULL JOIN in MYSQL
By the way, UNION
has optional keyword ALL
,when the ALL
is omitted, UNION
automatically selects DISTINCT
rows from the resultset.
EXAMLE:
SELECT *
FROM tableA
UNION ALL
SELECT *
FROM tableA
this can result duplicates rows
ColA ColB
==================
1 John
2 Jade
2 Jade
3 Hello
BUT if you omit the word ALL
SELECT *
FROM tableA
UNION
SELECT *
FROM tableA
this can result distinct rows only
ColA ColB
==================
1 John
2 Jade
3 Hello
MySQL: Using left join and union in one query
If you want to separate rows for a borrow/return combination, then union all
is appropriate. If so, I think this does what you want:
SELECT b.isbn, b.member_id, b.staff_id, date_borrowed, 'borrow' as which
FROM tblborrow b
UNION ALL
SELECT b.isbn, b.member_id, r.staff_id, date_returned, 'return' as which
FROM tblreturn r join
tblborrow b
on r.borrw_id = b.borrow_id;
Combine three tables with join an two with union
You need a join with subquery for union based on id
Select
t1.id, t1.naam, t2.lastname, t.Function
From
t1
Left Join
t2 On t2.t1 - id = t1.[id]
Left Join
t3 On t3.t2 - id = t2.[id]
Inner Join
(Select id, Function
From t2
Union
Select id, Function
From t3) t On t.id = t1.id
FULL OUTER JOIN with union subqueries
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
Related Topics
What Is the Affect of Convert() on Index While Searching
Simple Recursive Query in Oracle
Why Do SQL Id Sequences Go Out of Sync (Specifically Using Postgres)
Does SQL Server Optimize Dateadd Calculation in Select Query
Difference Between a Inline Function and a View
How to Prevent Ssis from Writing Column Names to the Flat File Output
How to Select a Column in SQL Server with a Special Character in the Column Name
Support for JSON in Oracle 11G
Orderby in SQL Server to Put Positive Values Before Negative Values
Notify My Wcf Service When My Database Is Updated
SQL How to Search a Many to Many Relationship
Return Value from MySQL Stored Procedure
Generating Xml File from SQL Server 2008
Get the Latest Records Per Group by SQL