I have written the following mysql query
SELECT distinct name, date
FROM table1
JOIN table2 ON (table2.item_id = table1.item_id)
where table1.id IN (SELECT run_id FROM
table3 where table3.status = 'FAIL') and table1.createdate >= '2011-01-01'
;
I want to include another field message from table3 in my output.
I guess this might involve joining 3 tables in the query.
Please let me know how to achieve this.
There's not quite enough info to fully answer the question. We also want to know:
Does the status column come from table1 or from table3
Can there be more than one table3 record with a runid that matches a table1.id value?
If there can be, which table3.message value do you want to show?
Without knowing that info, all we can do is guess. Here is my guess:
SELECT distinct name, date, message
FROM table1 t1
INNER JOIN table2 t2 ON t2.item_id = t1.item_id
INNER JOIN table3 t3 on t1.id =t3.run_id AND t3.status = 'FAIL'
WHERE t1.createdate >= '2011-01-01'
Try this :-
SELECT DISTINCT T1.NAME , T1.DATE , T3.MESSAGE
FROM TABLE1 T1
JOIN TABLE2 T2
ON
T1.ITEM_ID = T2.ITEM_ID
INNER JOIN TABLE3 T3
ON
T1.ID = T3.RUN_ID
WHERE T3.STATUS = 'FAIL' AND T1.CREATEDATE >= '2011-01-01';
Try this
SELECT distinct name, date, T3.message
FROM table1
JOIN table2 ON (table2.item_id = table1.item_id)
INNER JOIN (SELECT run_id FROM
table3 where status = 'FAIL') T3 ON T3.run_id = table1.id
where table1.createdate >= '2011-01-01'
try this :
select distinct name,date, message from table1 t1,table2 t2,table3 t3 where t1.item_id = t2.item_id and t1.item_id = t3.item_id
and t3.status ='FAIL' AND t1.createdate >= to_date('2011-01-01,'YYYY-DD-MM');
Related
I had a problem creating a MySQL query with a subquery.
I wanted to use some data from the main query on the subquery, as many times did.
But this time I wanted to use it in a JOIN and didn't worked. I really want to understand why this happens.
I will show you some examples that works and the one that didn't.
I made this simple structure to reproduce the example:
# table1
id field1
1 *first_value*
2 *another_value*
#table2
id field2
1 *second_value*
Using table1.id on the WHERE of the subquery to get a value, the most typical use for me (I know this can be a join, but i try to show the difference):
SELECT
t1.field1,
(
select t2.field2
FROM table2 as t2
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
You can use table1.id on the SELECT part too (not much sense in the example, but works):
SELECT
t1.field1,
(
select t1.id as field2
FROM table2 as t2
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
Now, if you try to use it on a JOIN inside the subquery, then, crashes:
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = t1.id
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
Kernel error: Error( 1054 ) 42S22: "Unknown column 't1.id' in 'on clause'"
Buuut, u can do the JOIN using the field in another subquery changing ON t3.id = t1.id to ON t3.id = (SELECT t1.id) ???
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = (SELECT t1.id)
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1'
I wonder to know why the third example query doesn't work while all others does.
Can someone explain this, please?
Thank you :)
That's because all elements in the ON clause of a JOIN, must belong the one of the joined tables, so as your t2.id must be equal to t1.id, you can do
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = t2.id
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
see the following SQL..
SELECT t1.*
FROM table1 t1
INNER JOIN table2 t2 ON t1.user_id = t2.id, tables3 t3
WHERE t3.id = 999
what kind of join is there here? between t1 and t3?. I mean what is the comma all about?
A , in the FROM clause is a deprecated shorthand for CROSS JOIN
A better way to write the query is with an explicit CROSS JOIN:
SELECT t1.*
FROM table1 t1 INNER JOIN
table2 t2
ON t1.user_id = t2.id CROSS JOIN
tables3 t3
WHERE t3.id = 999 ;
As written, the query makes no sense. Assuming that t3.id = 999 is true and appears once, then this is equivalent to:
SELECT t1.*
FROM table1 t1 INNER JOIN
table2 t2
ON t1.user_id = t2.id;
If the value doesn't exist, then no rows will be returned.
SELECT t1.*
FROM table1 t1
JOIN table2 t2 ON t1.user_id = t2.id
JOIN tables3 t3 ON t2.id=t3.id
WHERE t3.id = 999
I have 2 tables and result as shown in the image below: MySQL DB
What would be best way to join the two tables so we get the result as shown above.
SELECT * FROM (SELECT id, desc FROM table2) as T1
LEFT JOIN (SELECT * FROM table1) as T2 ON T1.id = T2.id
I guess my SQL is not working.
You can use a LEFT JOIN with COALESCE:
SELECT t1.id, COALESCE(t2.desc, t1.desc) AS desc, t1.D1, t1.D2
FROM table1 as T1
LEFT JOIN table2 as T2 ON T1.id = T2.id
Use a left join with coalesce to prioritize table 2's values if they are present, but fallback on table 1's values if not.
select t1.id,
coalesce(t2.desc, t1.desc) as desc,
t1.d1, t1.d2
from table1 t1
left join table2 t2
on t2.id = t1.id
order by t1.id
You can use ifnull:
SELECT t1.id, ifnull(t2.desc, t1.desc) AS desc, t1.D1, t1.D2
FROM table1 as T1
LEFT JOIN table2 as T2 ON T1.id = T2.id
coalesce or case .. when is also possible. All together with the left join
Please consider this query:
SELECT table1.* ,
(SELECT quantity FROM table2 WHERE id = table1.id AND table2.location = 10) quantity,
(SELECT reorder_level FROM table2 WHERE id = table1.id AND table2.location = 10) reorder_level,
(SELECT stock_date FROM table2 WHERE id = table1.id AND table2.location = 10) stock_date
FROM table1
WHERE category_id = 5 ORDER BY table1.id;
The aliases quantity, location and stock_date are obviously referencing a a row in table2 that fulfill the condition: id=table1.id and location=10.
This query works, but is probably suboptimal as a result of the clumsy subqueries.
How can I best join table1 to table2 USING(id) but only on rows where location is also 10.
TIP: One row from table1 has many rows in table2.
Unfortunately, the actual table definitions are much more complex, and I reckoned it might be counter-productive to dump the entire thing on this thread.
You can use additional condition in ON() part so it will join only rows which fulfills the provided criteria
SELECT t1.* ,
t2.quantity ,
t2.reorder_level,
t2.stock_date
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id AND t2.location = 10
WHERE t1.category_id = 5
ORDER BY t1.id;
Another way would be use a subselect for your table2 and select only rows where location is equal to 10
SELECT t1.* ,
t2.quantity ,
t2.reorder_level,
t2.stock_date
FROM table1 t1
LEFT JOIN
(SELECT * FROM table2 WHERE t2.location = 10) t2
ON t1.id = t2.id
WHERE t1.category_id = 5
ORDER BY t1.id;
I have some SQL code that returns me some data from DB
SELECT t1.id as id, title, description FROM table1 t1
JOIN table2 t2 ON t1.id = t2.t1_id
WHERE t2.t3_id IN( SELECT id FROM table3 WHERE parent_id IN ( SELECT id FROM table3 WHERE parent_id = 1)) GROUP BY t1.id
I have some problem with counting number of rows of result. I know that I have to write almost the same code but with COUNT but I have there A problem, my code doesn't return me a number of rows.
Just use the COUNT(*) function. Also, your subqueries can be converted to a JOIN (and your sub-subquery is redundant):
SELECT COUNT(*)
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.t1_id
JOIN table3 t2
ON t3.id = t2.t3_id
WHERE t3.parent_id = 1