LEFT OUTER JOIN and WHERE EXISTS. Are they equivalent? - mysql

I would like to create equivalent MySQL query using LEFT OUTER JOIN to WHERE EXISTS. I am following this question:
Are the SQL concepts LEFT OUTER JOIN and WHERE NOT EXISTS basically the same?
This is the original query:
SELECT *
FROM tableA
JOIN tableB ON tableA.tableA_id = tableB.tableB_id
JOIN tableC ON tableC.tableC_id = tableB.tableB_id
WHERE NOT EXISTS (
SELECT 1
FROM tableD
WHERE tableA.employee_id = tableD.employee_id AND tableC.tableC_datum = DATE(tableD.tableD_od_datetime)
)
But this query return different values:
SELECT *
FROM tableA
JOIN tableB ON tableA.tableA_id = tableB.tableB_id
JOIN tableC ON tableC.tableC_id = tableB.tableB_id
LEFT OUTER JOIN tableD ON tableA.employee_id = tableD.employee_id AND tableC.tableC_datum = DATE(tableD.tableD_od_datetime)
WHERE tableD.employee_id IS NULL AND DATE(tableD.tableD_od_datetime) IS NULL
Why are these two outputs not equivalent, please?

The not exists and left join ... rgt.col is null approaches are identical. The left join however will contain columns from the unwanted table so just be specific with the select clause:
SELECT table_a.*, table_b.*, table_c.*
FROM table_a
JOIN table_b ...
JOIN table_c ...
LEFT JOIN table_d ...
I would rather avoid * at all and explicitly list exactly those columns that I need.

Related

How to use subselection result as temp table in MySQL update query?

table A
uid
uname
temp table B
uid
uname
table B is not a real table but a result of subquery like
select uid, uname
from tableC left join tableD on tableC.pid = tableD.pid
where tableC.qid = tableD.qid
group by uid;
I want to update set A.uname = B.uname where A.uid = B.uid
how can I do that with MySQL?
Treat the subquery as a table in a JOIN:
UPDATE tableA AS a
JOIN (select uid, uname
from tableC
left join tableD on tableC.pid = tableD.pid and tableC.qid = tableD.qid
group by uid) AS b ON a.uid = b.uid
SET a.uname = b.uname
Also, note that in a LEFT JOIN, all the conditions that refer to the second table should be in the ON clause. Otherwise, you'll filter out all the non-matching rows, because the values of those columns will be NULL, and that will negate the point of using LEFT JOIN rather than INNER JOIN.
update a
set uname = B.name
from A a
inner join (
select uname [name]
from tableC left join tableD on tableC.pid = tableD.pid
where tableC.qid = tableD.qid
group by uid ) b
ON a.uid = b.uid

mysql case statement for joining three table

there is three table
table a
table b
table c
and my query is :
select a.title,a.id,b.title
from table a
case when a.type=1 then
inner join table a.id=tableb.id end
case when a.type=2 then inner join table a.id=table c.id
But this query doesnt work.Can somebody helpe the right way to fetch or execute this type of query
You cannot use case in the from clause. To achieve this you could use UNION ALL. For instance:
select a.title,a.id,b.title
from table a inner join table b on a.id=b.id
where a.type=1
UNION ALL
select a.title,a.id,c.title
from table a inner join table c on a.id=c.id
where a.type=2
You cannot do something like "if this is 1 then join other table than if it is 2", you must join both and select accordingly:
SELECT
a.title,
a.id,
IF (tableb.title IS NOT NULL, tableb.title, tablec.title),
CASE a.type
WHEN 1 THEN tableb.id
WHEN 2 THEN tablec.id
END
FROM table a
LEFT JOIN tableb ON tablea.id = tableb.id
LEFT JOIN tablec ON tablea.id = tablec.id

Help with JOINs in query

SELECT * FROM
Table_A
LEFT JOIN Table_B
ON (Table_A.A_ID = Table_B.A_ID)
INNER JOIN Table_C ON (Table_C.C_ID = Table_B.C_ID)
WHERE Table_A.ID = 3
This returns 0 rows, currently.
How can I set this up so I always get Table_A, even if there is no row for Table_B or Table_C. I still want to maintain the INNER JOIN between Table_B and Table_C, so that I will never get a B without a C.
Sub query the Table B and Table C. e.g.
SELECT *
FROM Table_A
LEFT JOIN
(SELECT *
FROM Table_B
INNER JOIN Table_C ON (Table_C.C_ID = Table_B.C_ID)
) B_AND_C ON (Table_A.A_ID = B_AND_C.A_ID)
WHERE Table_A.ID = 3
You may not have to use an inline view. I'm not in front of a machine with MySQL right now so I can't check but you can try
SELECT *
FROM table_A a
LEFT JOIN (table_B b
INNER JOIN table_C c
ON b.c_id = c.c_id)
ON a.b_id = b.b_id
WHERE
a.a_id =3

how do i select the required attributes from a union of left join and right join

I have two tables on which I am unable to perform full outer join so I am doing a union of left and right outer join.
each table has attributes like
tableA - one,two,three,four
tableB - one,two,three,four
(SELECT * FROM tableA
LEFT OUTER JOIN tableB ON
tableA.two=tableB.two)
UNION
(SELECT * FROM tableA
RIGHT OUTER JOIN tableB ON
tableA.two=tableB.two)
You just need to alias the tables
SELECT a1.one, a1.two, b1.one, b1.two
FROM tableA a1
LEFT OUTER JOIN tableB b1
ON a1.two=b1.two
UNION
SELECT a2.one, a2.two, b2.one, b2.two
FROM tableA a2
RIGHT OUTER JOIN tableB b2
ON a2.two=b2.two;
As an aside, the "UNION ALL and exclusion JOIN" method described on this page is a more reliable way of implementing FULL OUTER JOIN in MySQL.

Opposite of INNER JOIN with EXIST requirement

If inner join requires that a row exists, what's the opposite of it without having to do a sub query of NOT EXISTS?
I replaced
AND NOT EXISTS (
SELECT
*
FROM topic_read_assoc
WHERE topic_id = topic.id
AND member_id = ".$this->tru->application->currentMember->getId()."
)
with
OUTER JOIN topic_read_assoc ON (
topic_read_assoc.topic_id = topic.id AND
member_id = member_id = ".$this->tru->application->currentMember->getId()."
)
and it's not producing the same results as the first query (which works)
OUTER JOIN with a WHERE field IS NULL
Example:
SELECT A.name FROM A INNER JOIN B on A.id = B.id
Select those names in A whose id fields exist in B
Opposite:
SELECT A.name FROM A OUTER JOIN B on A.id = B.id WHERE B.id IS NULL
Select those names in A whose id fields do not exist in B
i think select on outer join is slow, because dbms left join first,then right join and delete the repeated rows.So I suggest you to select on the left join,then right join,make a intersect.It is better not operate on any join,because the view doesnt have index.