Query
select tablea.*,
tableb.id as tableb_id,
tableb.name as tableb_name,
tableb.settings,
tableb.logo
from tablea
left join tableb
on tableb.id = tablea.id
left join tablec
on tablec.id = tableb.id
where json_contains(tablea.fields, '2022-07-01', '$."date"."data"')
Description: The whereJsonContains not working with join when join didn't fill requirements. If tableb didn't have an entry in the reference of table1. The query didn't revert the result.
Related
Select * From tableA, TableB INNER JOIN tableC ON TableB.X = tableC.Y ==>OK
Select * From tableA, TableB LEFT JOIN tableC ON TableB.X = tableC.Y ==>ERROR
I replace the "LEFT JOIN" with "INNER JOIN" => Error
The error he gets is JOIN Expression not supported.
#VanThuyet:
You have to provide the join via a sub query:
Select * From tableA, (Select * From TableB LEFT JOIN tableC ON TableB.X = tableC.Y) As BC
I have a problem with the following query for id’s not present in tableC. Despite the LEFT JOIN, an id in tableA and tableB is not in the results if the id is absent from tableC. And that is because the tableC.name doesn’t exist for these id’s. I imagined MySQL would then ignore the last part considering the clause to be true….but no.
SELECT
tableA.id, tableA.name
FROM
tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON tableA.id = tableC.id
WHERE
tableA.latin = 'whatever'
AND RIGHT(tableC.name,2) != 'y'
I imagine there is a solution using either IF, CASE or EXISTS on the second part of the WHERE clause, but I don’t get the result I want with the following three attempts (I only show the last line):
WHERE
tableA.latin = 'whatever'
AND IF(tableC.name <> 0, RIGHT(tableC.name,2) != 'y', ' ');
This doesn’t give error either, but not the expected result:
WHERE
tableA.latin = 'whatever'
AND IF(tableC.name = true, RIGHT(tableC.name,2)!= 'y', ' ');
Trying the following with EXISTS gives me error in the MySQL Wordbench editor:
WHERE
tableA.latin = 'whatever'
AND if(EXISTS tableC.name, RIGHT(tableC.name,2) != 'y', ' ');
Any time you reference a column (tableC.name in your case) from a left-joined table in the where clause, you force the join to behave as if it were an inner join. Instead, move the test into the join condition.
SELECT tableA.id, tableA.name
FROM tableA
LEFT JOIN tableB
ON tableA.id = tableB.id
LEFT JOIN tableC
ON tableA.id = tableC.id
AND RIGHT(tableC.name,2) != 'y'
WHERE tableA.latin = 'whatever'
There is a much easier solution. Your where condition is turning the outer joins into inner joins. Just move the condition into the on clause:
SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON tableA.id = tableC.id AND RIGHT(tableC.name, 2) <> 'y'
WHERE tableA.latin = 'whatever';
Of course, the expression RIGHT(tableC.name,2) != 'y' should always be true almost always, because you are looking for two characters and comparing to one. Perhaps you mean:
SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON tableA.id = tableC.id AND tableC.name not like '%y'
WHERE tableA.latin = 'whatever';
How about this (untested but I think it should work):
SELECT tableA.id, tableA.name FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.id
LEFT JOIN tableC ON (tableA.id = tableC.id AND RIGHT(tableC.name,2) != 'y')
WHERE tableA.latin = 'whatever'
It makes table c only include the ones you want but doesn't interfere with the left outer join.
Assume tables TableA TableB TableC and TableD:
Is the following query:
TableA INNER JOIN TableB LEFT JOIN TableC LEFT JOIN TableD
(all joined to an id column) equivalent to:
TableA INNER JOIN TableB
INNER JOIN TableC
LEFT JOIN TableD
UNION
TableA INNER JOIN TableB
LEFT JOIN TableC ON TableB.c_id IS NULL
LEFT JOIN TableD
?
Note:
Or instead of union just do
TableA INNER JOIN TableB
INNER JOIN TableC
LEFT JOIN TableD
And then
TableA INNER JOIN TableB
LEFT JOIN TableC ON TableB.c_id IS NULL
LEFT JOIN TableD
and then combine the results
Update
Is
(A INNER JOIN B) LEFT JOIN C LEFT JOIN D
the same as:
A INNER JOIN (B LEFT JOIN C) LEFT JOIN D
?
Wikipedia:
"In mathematics, a binary operation is commutative if changing the order of the operands does not change the result. It is a fundamental property of many binary operations, and many mathematical proofs depend on it."
Answer:
no, a left join is not commutative. And inner join is.
But that's not really what you are asking.
Is the following query:
TableA INNER JOIN TableB LEFT JOIN TableC LEFT JOIN TableD
(all joined to an id column) equivalent to:
TableA INNER JOIN TableB
INNER JOIN TableC
LEFT JOIN TableD
UNION
TableA INNER JOIN TableB
LEFT JOIN TableC ON TableB.c_id IS NULL
LEFT JOIN TableD
Answer:
Also no. Unions and joins don't really accomplish the same thing, generally speaking. In some case you may be able to write them equivalently, but I don't think so general pseudo sql you are showing. The ON constitution seemslike it should not work (maybe something about which I do not know in MySQL?)
Here is a simplified set of queries that I do think would be equivalent.
SELECT *
FROM TableA a
LEFT JOIN
TableB b ON a.id = b.id_a
SELECT *
FROM TableA a
INNER JOIN
TableB b ON a.id = b.id_a
UNION
SELECT *
FROM TableA a
LEFT JOIN
TableB b ON a.id = b.id_a
WHERE TableB.id IS NULL
Edit 2:
Here's another example that is closer to your but in essence the same.
SELECT *
FROM TableA a
INNER JOIN TableB b ON a.id = b.id_a
LEFT JOIN TableC c ON b.id = c.id_b
is the same as
SELECT *
FROM TableA a
INNER JOIN TableB b ON a.id = b.id_a
INNER JOIN TableC c ON b.id = c.id_b
UNION
SELECT *
FROM TableA a
INNER JOIN TableB b ON a.id = b.id_a
LEFT JOIN TableC c ON b.id = c.id_b
WHERE TableC.id IS NULL
But I still don't think I'm answering your real question.
I have 2 tables in my database:
TableA contains aId, aBId, a3, ...
TableB contains bId, b2value, b3,...
aBId is a the bId of the tableB.
I need a mysql query that selects all the records from tableA where the record from bId has b2value = 'something'...
hate queries...
select a.*
from TableA a
inner join TableB b on a.aBid = b.bId
where b.b2Value = 'something'
select a.* from TableA a join TableB b on a.aBId = b.bId where
b.b2value = 'something'
select *
from TableA
inner join TableB on TableA.aBId = TableB.bId
where TableB.b2Value = 'something'
i have a general question about how sql server evaluates the joins.The query is
SELECT *
FROM TableA
INNER JOIN TableB ON TableB.id = TableA.id
LEFT JOIN TABLEC ON TABLEC.id = TABLEB.id
Q1: What tables is the left join based on? I know it will based on the TABLEC but what is the other one? Is it the result of the first inner join or the TABLEB specified in the left join condition?
Q2: Is "LEFT JOIN TABLEC ON TABLEC.id = TABLEB.id" equivalent to "LEFT JOIN TABLEC ON TABLEB.id = TABLEC.id"
Q3: Is the query equivalent to the following one? (with TABLEB.id replaced by TABLEA.id?)
SELECT *
FROM TableA
INNER JOIN TableB ON TableB.id = TableA.id
LEFT JOIN TABLEC ON TABLEC.id = TABLEA.id
Thank you!
Q1: It is based on the result of the inner join, therefore it will only LEFT JOIN with items that are in TableA AND TableB.
Q2: Yes
Q3: Yes, it's a consequence of question Q1.
SQL is a declarative language. When you declare 'A JOIN B JOIN C' there is no order of join involved. The end result has to match the required criteria, but the underlying implementation is free to choose any actual implementation order.
At a logical level the inner JOIN operator is associative so the order does not matter: 'A JOIN B JOIN C' is identical with 'A JOIN C JOIN B' which is identical with 'B JOIN A JOIN C' and so on and so forth.