I'm using this to join 3 tables
FROM TABLE_A LEFT JOIN TABLE_B ON A.Name = B.Name
LEFT JOIN TABLE_C ON A.Name = C.Name
Whenever I try something like
FROM TABLE_A LEFT JOIN TABLE_B ON A.Name = B.Name, A.Number = B.Number
LEFT JOIN TABLE_C ON A.Name = C.Name, A.Number = C.Number
It tells me I can only use one column for this operation. I need to join on two different columns though so I can't leave it at the first example. Using AND didn't help me either.
Try to replace the comma between the dual tests with an operator.
such as:
FROM TABLE_A LEFT JOIN TABLE_B ON A.Name = B.Name AND A.Number = B.Number
LEFT JOIN TABLE_C ON A.Name = C.Name AND A.Number = C.Number
Related
I want to join 2 tables and for each joined result I need a separate row, but the rows of my query result are somehow mixed:
Schema + Data:
My Query:
SELECT Table_A.id,
Table_B.id,
Table_C.id
FROM Table_A
LEFT JOIN Table_B
ON Table_B.id_a = Table_A.id
LEFT JOIN Table_C
ON Table_C.id_a = Table_A.id
The Result:
What I want (3 separate rows - separated by the join-tables' id-column):
Q: What am I doing wrong?
=> You could put it in that way: I need all rows of where id_a is 1 + table_a.id=1. Maybe JOIN is the wrong approach here..?
You need INNER JOIN UNION :
SELECT A.id A_Id, B.id B_Id, ''c_id
FROM Table_A A
INNER JOIN Table_B B ON B.id_a = A.id
UNION ALL
SELECT A.id A_Id, '' B_Id, c.id c_id
FROM Table_A A
INNER JOIN Table_C C ON A.id = C.id_a
I'm trying to join some tables with a query like below. Because I want to get the c.name ideally that the b table refers to. If the b table doesn't have rows in the result set or the b row doesn't refer to c, then just get the c.name that a table refers to.
SELECT a.*, c.name
FROM a
LEFT JOIN b ON a.b_id = b.id
LEFT JOIN c ON (b.c_id IS NOT NULL AND b.c_id = c.id) OR a.c_id = c.id
However mysql is always joining c with a.c_id = c.id and getting the less-favored c.name. Is it possible to avoid this, or is mySQL trying to get a full result set as quick as it can?
Try this may help:
SELECT a.*, c.name
FROM a
LEFT JOIN b ON a.b_id = b.id
LEFT JOIN c ON (b.c_id IS NOT NULL OR b.c_id = c.id) OR a.c_id = c.id
I think this should help:
SELECT a.*, c.name
FROM a
LEFT JOIN b ON a.b_id = b.id
LEFT JOIN c ON c.id = COALESCE(b.c_id, a.c_id)
When b.c_id is NULL, then a.c_id will be used. Otherwise b.c_id will be used.
It's not about speed. OR will give you all possible result rows including both b.c_id and a.c_id mappings for each row in a.
If you're not familiar with COALESCE(), the long form of this is almost exactly like your query but using IF() instead of OR.
SELECT a.*, c.name
FROM a
LEFT JOIN b ON a.b_id = b.id
LEFT JOIN c ON IF(b.c_id IS NOT NULL, b.c_id = c.id, a.c_id = c.id)
First of all, for example I have 3 table A, B, C. Table A has relation with table B and table has relation with table C. I want to get SUM of some field from table A which depends on some fields from table C.
Table A has > 300k rows, Table B has > 4k rows, Table C has ~ 100 rows
My query looks like that:
SELECT SUM(a.hours) AS total
FROM table_a a
LEFT JOIN table_b b
ON a.table_b_id = b.id
LEFT JOIN table_c c
ON b.table_c_id = c.id
WHERE a.customer_id = 1
AND c.title IN ('Title D','Title E')
Query execution time is ~7 sec, it's very slow. But execution time of query like below is ~0.0 sec.
SELECT a.hours
FROM table_a a
LEFT JOIN table_b b
ON a.table_b_id = b.id
LEFT JOIN table_c c
ON b.table_c_id = c.id
WHERE a.customer_id = 1
AND c.title IN ('Title D','Title E')
Why SUM is so slow? what should I do?
Move your condition to ON clause for related table:
SELECT SUM(a.hours) AS total
FROM table_a a
LEFT JOIN table_b b
ON a.table_b_id = b.id
LEFT JOIN table_c c
ON b.table_c_id = c.id
AND c.title IN ('Title D','Title E')
WHERE a.customer_id = 1
EDIT 1 According to #dnoeth comment I can agree, probably we should use inner join when join table_c:
SELECT SUM(a.hours) AS total
FROM table_a a
LEFT JOIN table_b b
ON a.table_b_id = b.id
INNER JOIN table_c c
ON b.table_c_id = c.id
AND c.title IN ('Title D','Title E')
WHERE a.customer_id = 1
Use LEFT JOIN in both places and add this composite index:
INDEX(customer_id, title)
I have the following query:
SELECT a.id, b.from, b.to FROM a INNER JOIN b ON a.id = b.from OR a.id = b.to;
which is extremely slow.
If I remove the OR clause and run each query separately then the both queries execute under 1 second.
SELECT a.id, b.from, b.to FROM a INNER JOIN b ON a.id = b.from;
SELECT a.id, b.from, b.to FROM a INNER JOIN b ON a.id = b.to;
How can I speed up the original query (set up indexes) or redesign the query itself?
What about using union?
SELECT a.id, b.from, b.to FROM a INNER JOIN b ON a.id=b.from
UNION
SELECT a.id, b.from, b.to FROM a INNER JOIN b ON a.id=b.to
How about the following instead. Just join to b twice:
SELECT a.id, b.from, b2.to
FROM a
INNER JOIN b ON a.id = b.from
INNER JOIN b b2 ON a.id = b2.to;
You may have to use LEFT JOIN instead if you don't always have a record for both cases.
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