Mysql - Left Join all tables - mysql

I have a query that looks like:
SELECT 'asdf', '123' ...
FROM table1
LEFT JOIN table2
on
(
condition1
)
LEFT JOIN table3
on
(
condition2
)
where
(
main_condition
)
Now the problem is, I need to conditionally include table1 as well. I tried this:
..
..
FROM table1
on
(
new_condition
)
..
..
but it wouldn't work. Please help.
EDIT (New finding):
In this post (http://blog.sqlauthority.com/2010/07/20/sql-server-select-from-dual-dual-equivalent/), I found this piece of code:
SELECT 1 as i, f.bar, f.jar FROM dual LEFT JOIN foo AS f on f.bar = 1 WHERE dual.dummy = ‘X’
UNION
SELECT 2 as i, f.bar, f.jar FROM dual LEFT JOIN foo AS f on f.bar = 2 WHERE dual.dummy = ‘X’
I'm sure it's not directly related to what I'm trying to do, but is it possible to JOIN a table to DUAL like that?

Dummy table:
Select a record from a dummy table first. dual is such a table, that is built in in MySQL for this exact purpose. I wrapped dual in a subselect, because MySQL apparently doesn't allow left joining against it.
SELECT 'asdf', '123' ...
FROM
(select 1 from dual) d
LEFT JOIN table1
on(
new_condition
)
LEFT JOIN table2
on
(
condition1
)
LEFT JOIN table3
on
(
condition2
)
Full (outer) join
Another solution, though different is using a full join or full outer join, which is like a left join and right join combined. It is quite different, though you can achieve a very similar result:
select
*
from
table1
full outer join table2 on joincondition.
In the query above, all records from both tables are returned, even if no matching record in either table exists.

Thanks for contributing to the discussion. I found the answer. It's really simple:
SELECT temp_table.* FROM
(SELECT 'asdf', '123' ... FROM DUAL) temp_table
LEFT JOIN table1
on
(
new_condition
)
LEFT JOIN table2
on
(
condition1
)
LEFT JOIN table3
on
(
condition2
)
where
(
main_condition
)
Interesting problem. Maybe I should favorite my own question this time :)

You need to include the condition in the on clause for the first join:
SELECT 'asdf', '123' ...
FROM table1 LEFT JOIN
table2
on condition1 AND new condition LEFT JOIN
table3
on condition2
where main_condition
When using a where clause with left join be careful. Normally, you want to move these conditions into the on clauses, because they can inadvertently undo the effect of the left outer join (turning it into an inner join).

you cant make this new condition in ON clause
on clause is just when you join, but you can add this new condition in where clause
example
where
(
main_condition
)
AND
(
new condition
)
EDIT:
try this
SELECT 'asdf', '123' ...
FROM (select 'asdf', '123' ... FROM table1 WHERE new_condition ) t
^^--your new condition here
LEFT JOIN table2
on
........
EDIT2: if your new condition can be wrong you can make an if statment
where
(
main_condition
)
AND
(
if(new condition is something , do something , else do something else)
)
edit3:
SELECT 'asdf', '123' ...
FROM (select 'asdf', '123' ... FROM table1 where main condition
UNION
select 'asdf', '123' ... FROM table1 WHERE new_condition ) t
^^--your new condition here
LEFT JOIN table2
on
........

My best guess with comments to date.
SELECT 'asdf', '123' ...
FROM table1
FULL OUTER JOIN table2 --NOTE THE FULL OUTER here all records in table 2 and only those that match in table 1
on
condition1 AND
new_condition=True
LEFT JOIN table3
on
(
condition2
)
where
(
main_condition
)

Related

Searching from three different tables with three different columns

How to search three different tables with three different columns? The current command:
$sql="select t1.brand_name,t2.category_name from brand_data_add AS t1
LEFT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name
UNION select t1.brand_name,t2.category_name from brand_data_add AS t1
RIGHT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name";
SQL:
SELECT
*
FROM
(
SELECT
workouts.name,
workouts.description,
`user`.user_email
FROM
workouts
LEFT JOIN `user` ON
workouts.created_by = `user`.iduser
UNION
SELECT
workouts.name,
workouts.description,
`user`.user_email
FROM
workouts
RIGHT JOIN `user` ON
workouts.created_by = `user`.iduser) AS main_table
WHERE
user_email LIKE '%gmail%';
Explanation:
You should enclose your union query with bracket
Fetch the fields with SELECT clause
Use the WHERE clause to do the conditional filter in virtual table main_table (union of two table)
select t1.brand_name,t2.category_name, t3.? from brand_data_add AS t1
LEFT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name
LEFT JOIN t3 on t3 on t3.? = t?
UNION select t1.brand_name,t2.category_name, t3.? from brand_data_add AS t1
RIGHT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name"
RIGHT JOIN t3 on t3 on t3.? = t?

SELECT union of results from same subquery in MySQL

Say I have a query which looks something like this:
select step0.a, step1.a, step2.a
from (select id from tbl1) as step
inner join tbl1 as step0 on step0.id = step.id
left join tbl1 as step1 on step1.b = step0.a
left join tbl1 as step2 on step2.b = step1.a
This works fine. Now, say I want to union these results with the reverse of a and b, i.e.:
select * from (
(
select step0.a, step1.a, step2.a
from (select id from tbl1) as step
inner join tbl1 as step0 on step0.id = step.id
left join tbl1 as step1 on step1.b = step0.a
left join tbl1 as step2 on step2.b = step1.a
)
union (
select step0.b, step1.b, step2.b
from (select id from tbl1) as step
inner join tbl1 as step0 on step0.id = step.id
left join tbl1 as step1 on step1.a = step0.b
left join tbl1 as step2 on step2.a = step1.b
)
) rows
This also works fine. But notice that the select id from tbl1 subquery is duplicated.
The question I have, is how do I store the results of this subquery, without using temporary tables, such that each select in the union can reference it?

INNER JOIN with more than one OR operators in WHERE clause increases the execution time

as we know - "INNER JOIN with complex condition dramatically increases the execution time please refer this"
consider the query
(
SELECT ...
FROM Table1
INNER JOIN Table2 ON Table1.P1 = Table2.P1 OR Table1.P2 = Table2.P2
)
Over here comparison will be done via "nested loops" so execution time will be more but if we have a query like-
(
SELECT ...
FROM Table1
INNER JOIN Table2 ON Table1.P3 = Table2.P3 where Table1.P1 = "abc" OR
Table2.p2 = "xyz"
)
or like-
(
SELECT ...
FROM Table1
INNER JOIN Table2 ON Table1.P3 = Table2.P3 where Table1.P1 LIKE "abc" OR
Table2.p2 LIKE "xyz"
)
than also does the comparison will take place through nested loops only (for columns P1 ANd P2)?
Please Use Union instead of 'OR' condition in JOIN.
SELECT ...
FROM Table1
INNER JOIN Table2 ON Table1.P1 = Table2.P1
UNION All
SELECT ...
FROM Table1
INNER JOIN Table2 ON Table1.P2 = Table2.P2 AND Table1.P1 <> Table2.P1

mySQL query to Retrieve only the records in left table

How to write a mysql query to get only the records in left table.
Left Join gives me all the records from T1 table and there is no MINUS in mySQL.
EDIT:
Do not wish to use sub queries
Use not exists:
select l.*
from `left` l
where not exists (select 1 from `right` r where r.id = l.id);
If you need more column comparisons, you can expand the logic:
select l.*
from `left` l
where not exists (select 1
from `right` r
where r.col1 = l.col1 and
r.col2 = l.col2 and
. . .
);
You are looking for a left excluding join
SELECT A.*
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL
See this Article on SQL join, it can be helpful
https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

LEFT OUTER JOIN with OR versus UNION

Are there significant performance considerations between using UNION versus LEFT OUTER JOIN with OR in the WHERE clause?
What is the difference between these two queries?
Is it often better to use LEFT OUTER JOINs instead of a UNION?
My reason for asking is I actually need to do an INSERT, and can't use a UNION even if I wanted to.
SELECT t.foo
FROM t
INNER JOIN t1 t1.t_id=t.id
WHERE t1.id IN (1,2,3)
UNION
SELECT t.foo
FROM t
INNER JOIN t2 t2.t_id=t.id
INNER JOIN t2a ON t2a.t2_id=t2.id
WHERE t2a.id IN (1,2,3)
UNION
SELECT t.foo
FROM t
INNER JOIN t3 t3.t_id=t.id
INNER JOIN t3a ON t3a.t3_id=t3.id
WHERE t3a.id IN (1,2,3);
SELECT DISTINCT t.foo
FROM t
LEFT OUTER JOIN t1 t1.t_id=t.id
LEFT OUTER JOIN t2 t2.t_id=t.id
LEFT OUTER JOIN t2a ON t2a.t2_id=t2.id
LEFT OUTER JOIN t3 t3.t_id=t.id
LEFT OUTER JOIN t3a ON t3a.t3_id=t3.id
WHERE t1.id IN (1,2,3) OR t2a.id IN (1,2,3) OR t3a.id IN (1,2,3);
UPDATE t
LEFT OUTER JOIN t1 t1.t_id=t.id
LEFT OUTER JOIN t2 t2.t_id=t.id
LEFT OUTER JOIN t2a ON t2a.t2_id=t2.id
LEFT OUTER JOIN t3 t3.t_id=t.id
LEFT OUTER JOIN t3a ON t3a.t3_id=t3.id
SET t.foo="bar"
WHERE t1.id IN (1,2,3) OR t2a.id IN (1,2,3) OR t3a.id IN (1,2,3);
As with many performance questions, you should test the results on your data and your systems. The union and left joins are doing very different things -- and which is better probably depends on features of your data, available indexes, and other considerations.
However, you can use the union method in update. You just need a subquery:
update t join
(select t.id, t1.foo . . .
union . . .
select t.id, t2.foo
) tt
on t.id = tt.id
set t.foo = 'foo'
where . . .;
You might also find it more efficient to use the union approach but to break the update into multiple separate update statements.
You can use UNION in inserts.
INSERT INTO `table`
SELECT * FROM
(
SELECT '1'
UNION
SELECT '2'
) x
Same goes for updates:
UPDATE `table1` t1
JOIN (
SELECT '1' as col1
UNION
SELECT '2'
) x ON x.col1 = t1.colX
SET t1.whateverColumn = "someValue"
As for performance, it's mainly down to indexes. Both can be fast, both can be slow. If you're indexing them correctly, you shouldn't see big differences between the two.