Can not join more than two table - mysql

I have 3 tables:
table1
fields : id, title, cat1_id
table2
fields : id, title, cat2_id
table3
fields : id, title
My SQL :
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
AND INNER JOIN table3 AS c ON c.id = b.cat2_id
ORDER BY a.id DESC
it's not working.
I try this SQL, it's working:
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
ORDER BY a.id DESC
but double INNER JOIN does not work.

You do not need to use AND before JOIN to join more that two tables.
Your query should be
SELECT a.id, a.title, b.title, c.title
FROM table1 AS a
INNER JOIN table2 AS b ON b.id = a.cat1_id
INNER JOIN table3 AS c ON c.id = b.cat2_id
ORDER BY a.id DESC
Have a look at MySQL JOIN Syntax

Related

How to count an inner join in MySQL

How could I count an inner join output, thanks a lot
-- Quantity A = 981
SELECT COUNT(DISTINCT ID) FROM A;
-- Quantity B = 673
SELECT COUNT(DISTINCT ID) FROM B;
How can i count an inner join
SELECT * FROM A
INNER JOIN B
ON A.ID = B.ID;
Combine your two attempts into one since you're performing an INNER JOIN, it does not matter if you use A.ID or B.ID in the DISTINCT COUNT:
SELECT COUNT(DISTINCT A.ID) AS AB_Count FROM A INNER JOIN B ON A.ID = B.ID;
Fiddle for reference.

MySql JOIN query with OR clause very slow

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 2 tables with for statement in sql

i have 2 table and want to select data from them
table 1 :
id
name
table 2
id
name
table1.id
and i want a query to make this resualt:
table1.id
table1.name
count(table2.id)
this is simple and solved by this way :
SELECT
c.id as corridor_id,
c.name as corridor_name,
(SELECT COUNT( r.id ) FROM rooms AS r WHERE r.corridorid = c.id ) as room_count
FROM corridors AS c
now if i add another table like this :
table3
id
name
table2.id
and want a query like this :
table1.id
table1.name
count(table2.id)
count(table3.id)
idk how can i do such as this query, but if there is a way i'll be happy to find it, many tnx
You'll want to join them all together, and then Group them along these lines:
SELECT
t1.Id,
t1.Name,
Count(t2.Id) AS T2Count,
Count(t3.Id) AS T3Count
FROM table1 t1
JOIN table2 t2
ON t1.Id = t2.table1_id
JOIN table3 t3
ON t2.id = t3.table2_id
GROUP BY t1.Id, t1.Name
You don't need nested SELECT statement here. You can do it by grouping and to avoid double-counting you would want DISTINCT keyword:
SELECT
c.id as corridor_id,
c.name as corridor_name,
COUNT(DISTINCT r1.id),
COUNT(DISTINCT r2.id)
FROM
corridors c
JOIN rooms r ON r.corridorid = c.id
JOIN rooms2 r2 ON r2.corridorid = c.id
GROUP BY c.id
If you want to properly treat missing values (0 counts) you can also do this:
SELECT
c.id as corridor_id,
c.name as corridor_name,
IFNULL(COUNT(DISTINCT r1.id), 0),
IFNULL(COUNT(DISTINCT r2.id), 0)
FROM
corridors c
LEFT JOIN rooms r ON r.corridorid = c.id
LEFT JOIN rooms2 r2 ON r2.corridorid = c.id
GROUP BY c.id

MySQL syntax for JOIN depending on condition

What would be a syntax of the following query:
Get all columns from Table1 and JOIN Table2 if matching reference (Table1ID) exists, otherwise JOIN Table3.
Simplified DB structure is more or less as below
Table1
ID Type
1 std
Table2
ID Table1ID Title Language
1 1 Test en
Table3
ID Table1ID Title Language Flag
1 1 Other en 1
Also, I now realized that Table3 will have multiple entries that refer to single Table1.id. How to limit it to return only the latest entry (with highest id) for every result?
If you don't want an entire separate set of columns for each join, this may be what you're looking for:
SELECT *
FROM (
SELECT a.ID AS Table1ID, a.Type, b.ID, b.Title, b.Language, NULL AS Flag
FROM Table1 a
JOIN Table2 b ON a.ID = b.Table1ID
UNION ALL
SELECT a.ID, a.Type, c.ID, c.Title, c.Language, c.Flag
FROM Table1 a
LEFT JOIN Table2 b ON a.ID = b.Table1ID
JOIN Table3 c ON a.ID = c.Table1ID
JOIN (
SELECT MAX(id) AS maxid
FROM Table3
GROUP BY Table1ID
) d ON c.ID = d.maxid
WHERE b.ID IS NULL
) a
ORDER BY a.Table1ID
SQLFiddle Demo
this is one way to do it.
select table1.id, table1.type, ifnull(table2.title, table3.title)
from table1
left join table2 on table1.id = table2.table1ID
left join table3 on table1.id = table3.table1ID

MySQL - Use select field value in nested SQL statement of the same SQL

I have the following SQL query
SELECT
a.id AS ID, a.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = ID
) AS other_titles
FROM table_a
However it is not working and is having a problem with the parts WHERE b.id = ID and WHERE b.another_id = ID in the nested SQL part.
How can I use the ID from the first select (SELECT a.id AS ID) in the nested select?
I think what you have here is called correlated subquery. It looks quite promising and seems to only lack a couple of final strokes (highlighted in bold italic):
SELECT
a.id AS ID,
a.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = a.ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = a.ID
) AS other_titles
FROM table_a AS a
Keep in mind that what you are actually referencing in the subquery is a.id, not the ID alias. (You can't reference the alias there.)
If a.id is a complex expression and you are not very happy about repeating it in the subquery, then you might need to restructure the entire query, maybe like this:
SELECT
x.ID,
x.title,
(
SELECT Group_Concat( title )
FROM (
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.id = x.ID
UNION
SELECT title
FROM `table_b` AS b
JOIN table_c ON c.id = b.id
WHERE b.another_id = x.ID
) AS other_titles
FROM (
SELECT
a.id AS ID,
a.title,
FROM table_a AS a
) x
You cannot select values into the FROM clause. You may only use variables to dynamically set the table name.