mysql no response if left join 2 inner join table - mysql

I have tried to run a SQL statment that Left Join 2 inner join statement, but the MYSQL cannot load the result.
TableA about 100,000 records and TableB about 200,000 records.
The statement is similar at the below :
(The job is about accounting matters, a aging report, and determine which voucher is not paid)
SELECT a.*, b.* FROM
(SELECT tableA JOIN tableB ON tableA.id = tableB.id WHERE tableB.dramt != 0) a
LEFT JOIN
(SELECT tableA JOIN tableB ON tableA.id = tableB.id WHERE tableB.cramt != 0) b
ON a.invoiceno = b.invoiceno
I have tried to run the INNER JOIN statement separately, the result has returned in less than a second.
Is it about the server setting? Anyone has similar experience? Please kindly give me some advice with thanks.

Related

LEFT OUTER JOIN and WHERE EXISTS. Are they equivalent?

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.

How to remove this subquery from this SQL statement?

I have a SQL statement that does left join with a table:
select a.id, b.col1 from tableA a
left join (select col1 from tableB where date = 'xxx') b on a.id = b.id
For some application constraint (I need to use Spring JPQL query that does not permit subquery), I need to "flatten" this query to remove the subquery without changing the meaning of the query: I want to enrich tableA with a subset of tableB.
I have tried a few queries such as:
select a.id, b.col1 from tableA a
left join tableB b on a.id = b.id
where (date = 'xxx' or date is null)
But that gave me different set of answer from previous query.
How do I remove this subquery?
It can be done in multiple different ways - using cte, using joins
Using join it can be implemented as -
select a.id, b.col1 from tableA a left join tableB b on a.id = b.id and b.date = 'xxx'
using CTE it can be implemented as -
with t as
(
select col1, id from tableB where date = 'xxx'
)
select a.id, b.col1 from tableA a
left join t on a.id = t.id

MySQL: How to Join to first row

I have 3 tables, Master with other two TableA and TableB, and Master has both one to many relationship with the other two tables.
What I want is to get all master records associated with only the latest record from both TableA and TableB, so I use left joins as below,
SELECT
*
FROM
Master master
LEFT JOIN (SELECT ta.* FROM TableA ta WHERE ta.masterId = master.id LIMIT 1 ORDER BY ta.id DESC ) as tableA
LEFT JOIN (SELECT tb.* FROM TableB tb WHERE tb.masterId = master.id LIMIT 1 ORDER BY tb.id DESC ) as tableB
WHERE master.status = 1
However above sql statement hit an error,
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'ta' from one of the SELECTs cannot be used in global ORDER clause
; bad SQL grammar ... Table 'ta' from one of the SELECTs cannot be used in global ORDER clause
It complains .. in global ORDER clause, but it doesn't seem like that, all order clauses are used in the subquery?
Where is wrong with my sql, it might be naive but is there a better way to achieve my requirement?
Loads of thanks.
You should fetch last record of tablea, tableb for each masterId first, then left join tablea and tableb to get all the records:
select m.*, ta.*, tb.*
from master m
left join (
select tablea.*
from tablea
join (select max(id) as id from tablea group by masterId) tmp
on tablea.id = tmp.id
) ta on ta.masterId = m.id
left join (
select tableb.*
from tableb
join (select max(id) as id from tableb group by masterId) tmp
on tableb.id = tmp.id
) tb on tb.masterId = m.id
The LIMIT 1 AND ORDER BY clauses should switch places

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

How sql server evaluates the multiple different joins?

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.