How do I outer join two mysql queries? - mysql

Let's say there are 4 tables , such that
t1.id = t2.pid
and
t3.id = t4.pid
How do I fetch records where t1.val1 != t3.val1 AND t2.val2 != t4.val2?

You need to use LEFT OUTER JOIN to find non matching records from two tables.
SELECT *
FROM t1
INNER JOIN t2
ON t1.id = t2.pid
LEFT OUTER JOIN t3
ON t2.pid = t3.id
LEFT OUTER JOIN t4
ON t3.id = t4.pid
WHERE (t1.val1 IS NULL OR t3.val1 IS NULL)
AND (t2.val2 IS NULL OR t4.val2 IS NULL)
Visit: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Related

Multiple JOIN and OR in WHERE clause MySQL query optimization

I'm trying to optimize a query similar to this one:
SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.t2_id = t2.id
LEFT OUTER JOIN table3 t3 ON t1.t3_id = t3.id
LEFT OUTER JOIN table4 t4 ON t3.t4_id = t4.id
LEFT OUTER JOIN table5 t5 ON t3.t5_id = t5.id
LEFT OUTER JOIN table6 t6 ON t1.t6_id = t6.id
WHERE (t1.attribute1 = ? OR t2.attribute2 = ?)
AND t1.active = 1
AND t1.status <> 10
what I saw in the logs is that what takes most is the OR in the WHERE clause (with the OR the query takes ~1s for its execution, while without it it takes around ~400 ms with the data that I've sampled from the DB).
I'm looking for alternatives to get the same results without taking much time (also, performance decreases if many queries are executed concurrently).
I've tried replacing the OR with an union subquery with a join between t1 and t2 (I'm working with MySQL 5.7):
SELECT * FROM (SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.t2_id = t2.id
WHERE t1.attribute1 = ?
UNION
SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.t2_id = t2.id
WHERE t2.attribute2 = ?
) AS joined
LEFT OUTER JOIN table3 t3 ON joined.t3_id = t3.id
LEFT OUTER JOIN table4 t4 ON t3.t4_id = t4.id
LEFT OUTER JOIN table5 t5 ON t3.t5_id = t5.id
LEFT OUTER JOIN table6 t6 ON joined.t6_id = t6.id
WHERE joined.active = 1
AND joined.status <> 10
But I'd like to know if there is a better approach for optimizing the query.
EDIT: active, status, attribute1 and attribute2 are indexed as well as the ids.
The following index can increase the performance of the first query, as long as your are not selecting too many rows (ideally less than 1000 rows):
create index ix1 on table1 (attribute1, active, status, t2_id);
Add this index. If it's still slow, add the execution plan to your question.

Mysql LEFT JOIN multiple times

I run:
SELECT
t2.n, t3.n, t4.n,... tn.n
FROM t1
LEFT JOIN (SELECT ... FROM a LEFT JOIN b ON...) t2 ON t2.id = t1.c2
LEFT JOIN (SELECT ... FROM a LEFT JOIN b ON...) t3 ON t3.id = t1.c3
LEFT JOIN (SELECT ... FROM a LEFT JOIN b ON...) t4 ON t4.id = t1.c4
...
LEFT JOIN (SELECT ... FROM a LEFT JOIN b ON...) tn ON t4.id = t1.cn
All contents in bracket are the same:
SELECT ... FROM a LEFT JOIN b ON...
How can I call it 1 time instead of 'n' times as above?
t2.n, t3.n, t4.n,... tn.n have different values
I haven't try it you can try following code:
SELECT ... FROM t1
LEFT JOIN (SELECT ... FROM a LEFT JOIN b ON...) t2
ON
t2.id = t1.c2 OR
t2.id = t1.c3 OR
t2.id = t1.c4 OR
t2.id = t1.cn

I Only Know 2 Tables in Left Join SQL Query. What if I have 3 or More Tables?

I'm creating sql command where the date stored in different table with foreign key of borrowers_id. I can execute and output left join of 2 tables but what if I have 3 or more tables fetching the datas of my foreign key.
Here's my SQL command,
SELECT borrowers.firstname,
borrowers.middlename,
borrowers.lastname,
borrowers.home_address,
borrowers.date_of_birth,
borrowers.age,
borrowers.residential_status,
borrowers.status,
borrowers.date_added,
borrowersp.spouse_name,
borrowersp.date_of_birth,
borrowersp.age
FROM tblborrowers as borrowers LEFT JOIN tblborrowerspouse as borrowersp
ON borrowers.borrowers_id = borrowersp.borrowers_id
WHERE borrowers.borrowers_id=23432413;
You can add more tables by continuing to join:
FROM tblborrowers as borrowers LEFT JOIN tblborrowerspouse as borrowersp
ON borrowers.borrowers_id = borrowersp.borrowers_id
LEFT JOIN tblborrowerskid as kid
ON borrowers.borrowers_id = kid.parent_id
WHERE borrowers.borrowers_id=23432413;
You can add as many as you'd need.
Lets say you have tables : t1 ,t2 and t3 ..Left Joining :
SELECT t2.id, t1.id AS Expr1
FROM t3 LEFT JOIN
t1 ON t3.id = t1.id LEFT JOIN
t2 ON t1.id = t2.id
We can also write the above query with left outer join :
SELECT t2.id, t1.id AS Expr1
FROM t3 LEFT OUTER JOIN
t1 ON t3.id = t1.id LEFT OUTER JOIN
t2 ON t1.id = t2.id
For 5 tables ..t1,t2,t3,t4 and t5 :
SELECT t2.id, t1.id AS Expr1, t5.id AS Expr2, t4.id AS Expr3
FROM t5 LEFT OUTER JOIN
t1 ON t5.id = t1.id LEFT OUTER JOIN
t4 ON t1.id = t4.id LEFT OUTER JOIN
t3 ON t1.id = t3.id LEFT OUTER JOIN
t2 ON t1.id = t2.id
Please have a look at this SO post :
What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?

how to join three table on base of ncarpk in mysql

I want check ncarpk in tour_customer, tour_provider, reservation if any table have record with ncarpk = 7, then show result.
select *
from tour_customer
Left Outer join tour_provider on tour_provider.nCarPk = '7'
Left Outer join reservation on reservation.nCarPk = '7'
where tour_customer.ncarpk = '7'
i would try
select *
from tour_customer
Left Outer join tour_provider on tour_provider.nCarPk =customer.ncarpk
Left Outer join reservation on reservation.nCarPk = customer.ncarpk
where tour_customer.ncarpk = '7'
This is the normal way to make joins, you say on which field you want to make the join and then you add the where clause.
Well it is ugly without full join in mysql. You can use unions instead:
Select t1.id,t2.id,t3.id from
t1 left outer join t2 on t1.id = t2.id
left outer join t3 on t1.id = t3.id
where t1.id = 7 or t2.id = 7 or t3.id = 7
union
Select t1.id,t2.id,t3.id from
t2 left outer join t1 on t1.id = t2.id
left outer join t3 on t2.id = t3.id
where t1.id = 7 or t2.id = 7 or t3.id = 7
union
Select t1.id,t2.id,t3.id from
t3 left outer join t2 on t3.id = t2.id
left outer join t1 on t1.id = t3.id
where t1.id = 7 or t2.id = 7 or t3.id = 7
Here is fiddle http://sqlfiddle.com/#!9/f4576/2 .
Change to your tables instead of t1,t2,t3 and change id with nCarPK.

Easy way to left join parent data to multiple left join child data

Is there an easier way to left join parent data to multiple child left join data?
Table Structure:
Table1 {id, name, data1, data2, datax}
Table2 {id, table1_id, dataA, dataB, userid}
Table3 {id, table1_id, dataD, userid}
Table4 {id, table1_id, dataE, userid}
TableUsers {userid, username, name, email}
SQL Query:
select Table1.*, Table2.*,Table3.*,Table4.*
from Table1 t1
left outer join Table2 t2 on t2.table1_id = t1.id
left outer join Table3 t3 on t3.table1_id = t1.id
left outer join Table4 t4 on t4.table1_id = t1.id
From here I want to replace the userid field with the actual user name and each table will have different data for userid so a simple left join with TableUsers won't work since it will only take affect for the table it is set equal to.
I have thought about doing it with a sub query, but believe that would be extra slow:
select Table1.*,(select TableUser.name from TableUser where Table1.userid = TableUser.userid) as T1Name,
Table2.*,(select TableUser.name from TableUser where Table2.userid = TableUser.userid) as T2Name,
Table3.*, (select TableUser.name from TableUser where Table3.userid = TableUser.userid) as T3Name,
Table4.*,(select TableUser.name from TableUser where Table1.userid = TableUser.userid) as T4Name
from Table1 t1
left outer join Table2 t2 on t2.table1_id = t1.id
left outer join Table3 t3 on t3.table1_id = t1.id
left outer join Table4 t4 on t4.table1_id = t1.id
The point of this is to move from an SQL database to MongoDB. Perhaps I need to rethink this entire query...
Cheers,
Chip
The "normal" way to do this would be to add additional joins:
select Table1.*, t1name.name, Table2.*, t2name.name, Table3.*, t3name.name,
Table4.*, t4name.name
from Table1 t1
left outer join Table2 t2 on t2.table1_id = t1.id
left outer join Table3 t3 on t3.table1_id = t1.id
left outer join Table4 t4 on t4.table1_id = t1.id
left outer join TableUser t1name on t1.userid = t1name.userid
left outer join TableUser t2name on t2.userid = t2name.userid
left outer join TableUser t3name on t3.userid = t3name.userid
left outer join TableUser t4name on t4.userid = t4name.userid;
If you have an indexon TableUser(userid) or TableUser(userid, name), then the performance of the two methods should be about the same.