I have 3 tables that i want to run a query on, what im trying to do is as follows:
TABLE1.name , TABLE1.description, TABLE2.category.
The link between TABLE2 and TABLE1 is the product_ID and category_ID which both are on TABLE3
So here's the query im trying to run
SELECT table1.name AS product_name,
table1.description AS product_description,
table2.name AS product_category
table3.product_id
FROM table1
INNER JOIN table1 a ON table3.product_id = table1.product_id
INNER JOIN table2 b ON table3.category_id = table2.category_id
INNER JOIN table2 ON table1.product_id = table2.product_id;
The structure of the tables is as follows :
Table1(product_id,name,description)
Table2(category_id,name2)
Table3(product_id,category_id)
If you use assign alias (table1 a, table 2 b) to table then use it otherwise don't assign.
You are Joining two time table 2 but not table 3 and assuming that table2 and table1 are related by category_id
and table3 table1 are related by both product_id and category_id
SELECT
table1.name AS product_name
,table1.description AS product_description
,table2.name AS product_category
,table3.product_id
FROM table1
INNER JOIN table2 table1.category_id = table2.category_id ;
INNER JOIN table3 ON table3.product_id = table1.product_id
and table3.category_id = table1.category_id
where is your condition of Table1.category_id = Table2.category_id ?
Related
I have these MySQL tables:
table1:
id | writer
1 | Bob
2 | Marley
3 | Michael
table2:
user_one | user_two
1 | 2
And this query:
SELECT table1.id FROM table1 LEFT JOIN table2 ON table1.id = table2.user_one
This query will return all rows of table1 which are 1,2,3
I want to select only rows which are not found in the left joint. So it should return only row with id 3
I want sort of the opposite of INNER JOIN which will select only the rows which are found in the join. How to get the opposite like if left join exists, ignore it and move to the next row. Hope i'm clear
You could use the following query:
SELECT table1.id
FROM table1
LEFT JOIN table2
ON table1.id IN (table2.user_one, table2.user_two)
WHERE table2.user_one IS NULL;
Although, depending on your indexes on table2 you may find that two joins performs better:
SELECT table1.id
FROM table1
LEFT JOIN table2 AS t1
ON table1.id = t1.user_one
LEFT JOIN table2 AS t2
ON table1.id = t2.user_two
WHERE t1.user_one IS NULL
AND t2.user_two IS NULL;
One of the best approach if you do not want to return any columns from table2 is to use the NOT EXISTS
SELECT table1.id
FROM table1 T1
WHERE
NOT EXISTS (SELECT *
FROM table2 T2
WHERE T1.id = T2.user_one
OR T1.id = T2.user_two)
Semantically this says what you want to query: Select every row where there is no matching record in the second table.
MySQL is optimized for EXISTS: It returns as soon as it finds the first matching record.
One more note to this:
When you check against a nullable column in the joined table, depending on your needs, you may have to use NOT EXISTS (or check against other columns when using LEFT JOIN), because MySQL won't be able to distinguish between a column which is NULL, but there is an existing record in the joined table and a column which is generated as NULL because the joined table have no matching record.
Here is a query that returns only the rows where no correspondance has been found in both columns user_one and user_two of table2:
SELECT T1.*
FROM table1 T1
LEFT OUTER JOIN table2 T2A ON T2A.user_one = T1.id
LEFT OUTER JOIN table2 T2B ON T2B.user_two = T1.id
WHERE T2A.user_one IS NULL
AND T2B.user_two IS NULL
There is one jointure for each column (user_one and user_two) and the query only returns rows that have no matching jointure.
Hope this will help you.
SELECT table1.id
FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one is NULL
Try following query:-
SELECT table1.id
FROM table1
where table1.id
NOT IN (SELECT user_one
FROM Table2
UNION
SELECT user_two
FROM Table2)
Hope this helps you.
Try:
SELECT A.id FROM
(
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one IS NULL
) A
JOIN (
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_two
WHERE table2.user_two IS NULL
) B
ON A.id = B.id
See Demo
Or you could use two LEFT JOINS with aliases like:
SELECT table1.id FROM table1
LEFT JOIN table2 A ON table1.id = A.user_one
LEFT JOIN table2 B ON table1.id = B.user_two
WHERE A.user_one IS NULL
AND B.user_two IS NULL
See 2nd Demo
I have the following data in the database in table1
I run the following query and returns nothing
SELECT
someColumns
FROM table1
INNER JOIN table2 ON table1.id = table2.id
INNER JOIN table3 ON table1.anotherId = table3.anotherId
I want to return all the records in (table2 with id = table1.id and table3 with anotherId = table1.anotherId)
You should using LEFT OUTER JOIN to get the specified result.
I have three tables with following data
Table 3 :
Table1_id Table2_id
1 1
1 2
1 3
2 1
2 3
3 2
Table 2 :
Table2_id Name
1 A
2 B
3 C
Table 1 :
Table1_id Name
1 P
2 Q
3 R
I have a problem where I need to return all table1_id's which have an entry for all Table2_ids's in Table 3.
ie. I want my output to be
Table1_id
1
I found a solution using count().
But is there a way to use all() or exists() to solve the query?
Using NOT IN with excluding LEFT JOIN in a subselect with a CROSS JOIN
select *
from table1
where Table1_id not in (
select t1.Table1_id
from table1 t1
cross join table2 t2
left join table3 t3 using (Table1_id, Table2_id)
where t3.Table1_id is null
)
VS using COUNT()
select table1_id
from table3
group by table1_id
having count(1) = (select count(1) from table2)
Explanation:
The CROSS JOIN
select t1.Table1_id
from table1 t1
cross join table2 t2
represents how table3 would look like, if every item from table1 would be related to every item from table2.
A (natural) left join with table3 will show us which relations really exists. Filtering by where t3.Table1_id is null (excluding LEFT JOIN) we get the missing relations. Using that result for the NOT IN clause, we get only table1 items that have no missing relation with table2.
You can use the following query:
SELECT DISTINCT t1.*
FROM Table2 AS t2
CROSS JOIN Table1 AS t1
WHERE NOT EXISTS (SELECT 1
FROM Table3 AS t3
WHERE t1.Table1_id = t3.Table1_id AND
t2.Table2_id = t3.Table2_id)
to get Table1 records not having a complete set of entries from Table2 in Table3. Then use NOT IN to get the expected result.
Here is a solution using EXISTS and INNER JOIN.
SELECT DISTINCT t3_out.Table1_id FROM Table3 t3_out
WHERE EXISTS( SELECT 1
FROM Table2 t2 INNER JOIN Table3 t3 ON t2.Table2_id = t3.Table2_id
WHERE t3.Table1_id = t3_out.Table1_id
HAVING COUNT(DISTINCT t2.Table2_id) = 3 )
I have these MySQL tables:
table1:
id | writer
1 | Bob
2 | Marley
3 | Michael
table2:
user_one | user_two
1 | 2
And this query:
SELECT table1.id FROM table1 LEFT JOIN table2 ON table1.id = table2.user_one
This query will return all rows of table1 which are 1,2,3
I want to select only rows which are not found in the left joint. So it should return only row with id 3
I want sort of the opposite of INNER JOIN which will select only the rows which are found in the join. How to get the opposite like if left join exists, ignore it and move to the next row. Hope i'm clear
You could use the following query:
SELECT table1.id
FROM table1
LEFT JOIN table2
ON table1.id IN (table2.user_one, table2.user_two)
WHERE table2.user_one IS NULL;
Although, depending on your indexes on table2 you may find that two joins performs better:
SELECT table1.id
FROM table1
LEFT JOIN table2 AS t1
ON table1.id = t1.user_one
LEFT JOIN table2 AS t2
ON table1.id = t2.user_two
WHERE t1.user_one IS NULL
AND t2.user_two IS NULL;
One of the best approach if you do not want to return any columns from table2 is to use the NOT EXISTS
SELECT table1.id
FROM table1 T1
WHERE
NOT EXISTS (SELECT *
FROM table2 T2
WHERE T1.id = T2.user_one
OR T1.id = T2.user_two)
Semantically this says what you want to query: Select every row where there is no matching record in the second table.
MySQL is optimized for EXISTS: It returns as soon as it finds the first matching record.
One more note to this:
When you check against a nullable column in the joined table, depending on your needs, you may have to use NOT EXISTS (or check against other columns when using LEFT JOIN), because MySQL won't be able to distinguish between a column which is NULL, but there is an existing record in the joined table and a column which is generated as NULL because the joined table have no matching record.
Here is a query that returns only the rows where no correspondance has been found in both columns user_one and user_two of table2:
SELECT T1.*
FROM table1 T1
LEFT OUTER JOIN table2 T2A ON T2A.user_one = T1.id
LEFT OUTER JOIN table2 T2B ON T2B.user_two = T1.id
WHERE T2A.user_one IS NULL
AND T2B.user_two IS NULL
There is one jointure for each column (user_one and user_two) and the query only returns rows that have no matching jointure.
Hope this will help you.
SELECT table1.id
FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one is NULL
Try following query:-
SELECT table1.id
FROM table1
where table1.id
NOT IN (SELECT user_one
FROM Table2
UNION
SELECT user_two
FROM Table2)
Hope this helps you.
Try:
SELECT A.id FROM
(
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_one
WHERE table2.user_one IS NULL
) A
JOIN (
SELECT table1.id FROM table1
LEFT JOIN table2 ON table1.id = table2.user_two
WHERE table2.user_two IS NULL
) B
ON A.id = B.id
See Demo
Or you could use two LEFT JOINS with aliases like:
SELECT table1.id FROM table1
LEFT JOIN table2 A ON table1.id = A.user_one
LEFT JOIN table2 B ON table1.id = B.user_two
WHERE A.user_one IS NULL
AND B.user_two IS NULL
See 2nd Demo
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