Mysql Query optimization - mysql

Below is my Table Structure
Table 1
id
name
Table 2
id
table1_id
I want the rows from table 1 which have no reference value in table 2.
Example data:
Table 1
id name
1 demo
2 demo2
3 demo3
Table 2
id table1_id
1 1
2 1
3 1
4 3
5 3
So there is no value in table 2 with table1_id 2. I want id 2 from Table 1.
Below id the query i have tried:
SELECT l.id FROM Table1 l WHERE l.id NOT IN (SELECT DISTINCT(r.id) FROM table2 r);
This is returning a proper result but its taking more than 2 minutes to process.
In table 1 i have 4000 rows and in table 2 I have 40000 rows.
Any optimisation to above query or any alternative solution?

SELECT * FROM table1 LEFT JOIN table2
ON table1.id=table2.table1_id
WHERE table2.table1_id IS NULL

Have an index for Table1.id and Table2.table1_id, then try the following query:
SELECT Table1.id FROM Table1
WHERE Table1.id NOT IN (SELECT Table2.id FROM Table2 group by Table2.table1_id);

What you are trying to acheive is to find orphan records right?
A join that shows all the records from the first(the left) table and the matching values form the other or nulls for no matches is called a left join. I think a left join will do the same job but it is not going to be any faster. Joins are in general slower.
I found a place where it is all well explained - http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/
It does not hurt to try with a join though, and tell us were your results the same as expected.

select t1.id from table1 as t1
left outer join table2 as t2
on t2.table1_id = t1.id
where t2.id is null;
or
select t1.id from table1 as t1
where not exists (select 1
from table2 as t2 where t2.table1_id = t1.id);

Related

Join two tables... without JOIN

I've got two tables T1 and T2, both with a single field (id).
T1.id has values:
1
2
4
T2.id has values:
1
3
4
I need to join these tables.
Desired result:
T1 | T2
------|------
1 | 1
2 | null
null | 3
4 | 4
With JOIN I'd do it easily:
Query 1
SELECT * FROM T1 FULL JOIN T2 ON T1.id=T2.id
But due to certain reasons I can't use JOIN here. So, with a simple query like this
Query 2
SELECT * FROM T1, T2 WHERE T1.id=T2.id
I would get only two rows of data
T1 | T2
------|------
1 | 1
4 | 4
as two other rows would be omitted due to no matches in the other table.
No matter what to fill the missing matches with. It could be NULL or any other value - really anything, but I need to get those omitted rows.
Is there a way to modify Query 2 to get the desired result without using any JOIN?
PS: Real tables are different in structure, so UNION is not allowed either.
PPS: I've just given a model to point out the problem. In reality it's a "megaquery" involving many tables each having dozens of columns.
Standard way to implement FULL OUTER JOIN when only implicit joins are supported.
select t1.id t1id, t2.id t2id
from t1, t2 where t1.id = t2.id
union all
select id, null from t1
where not exists (select 1 from t2 where t2.id = t1.id)
union all
select null, id from t2
where not exists (select 1 from t1 where t1.id = t2.id)
order by coalesce(t1id, t2id)
The first SELECT produces the INNER JOIN part of the result.
The second SELECT adds the additional LEFT OUTER JOIN rows to the result.
The third SELECT adds the additional RIGHT OUTER JOIN rows to the result.
All together, a FULL OUTER JOIN is performed!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ec154ad243efdff2162816205fdd42b5
SELECT t1.id t1_id, t2.id t2_id
FROM ( SELECT id FROM table1
UNION DISTINCT
SELECT id FROM table2 ) t0
NATURAL LEFT JOIN table1 t1
NATURAL LEFT JOIN table2 t2

sql join request

Well, i'm trying to make a sql request with join but i don't know how to do it.
Here my first table - Table 1
id
postid
user
My second table - Table 2
id
title
Postid and id are the same.
i've done a screenshot of my table 1
As you can see, there are many entries with postid 32. This is totally normal.
I want to do a sql request on this 2 tables.
The results expected have to be like this :
Title of id 31 (from table 1) - 2 (because there are 2 entries with postid 31 in table 2)
Title of id 32 (from table 1) - 23 (because there are 23 entries with postid 32 in table 2)
Someone can help me ?
Try this:
select t1.postid, count(t2.id)
from Tab1 t1 join Tab2 t2
on t1.postid = t2.id
group by t1.postid;
Here the name of the tables are Tab1 and Tab2 and they have aliases t1 and t2.
If you are interested only in the postids of table1 then there is no need for a join:
select postid, count(*)
from table1
group by postid;
If you want to count all the ids of table2 even the ones that are missing in table1 then you need a left join:
select t2.id, count(t1.postid)
from table2 t2 left join table1 t1
on t1.postid = t2.id
group by t2.id;

MySQL: Get data from multiple tables allowing nulls with a list of ids

I got this tables that look like this:
table 1
|id|value1|value2|value3
table 2
|id|value4|value5|value6
The id value in each table is unique but an id could appear in a table 1 but no in table 2. (value 1 is equal to value4 but if id dont appear in table 2 value4 would be null... )
Then I got this a of ids and I want to get sometime like (supossing that id appear in table 1 but no in 2 and vice versa):
resultgrid
| id | value1| value2| value3|value4|value5|value6
|838383|result1|result2|result3|null |null |null
|548438|null |null |null |result4|result5|result6
hope you guys can help me, thanks!
EDIT: query i've been trying (it's actually a set of collected pieces of answer i'd see in stack overflow)
SELECT t1.*, t2.value4, t2.value5, t2.value6
FROM table1 as t1
JOIN table2 AS t2 ON t2.id = t1.id
Where t1.id = t2.id = 838383
this get me 0 rows returned.
I want to make it general to use the <2000 id list.
You want a full outer join which MySQL does not support. In your case, you can emulate this with left join:
select t1.*, t2.value4, t2.value5, t2.value6
from (select 838383 as id
) i left join
table1 t1
on t1.id = i.id left join
table2 t2
on t2.id = i.id;
The list of ids you want to keep goes in the i subquery.
You can use two different Select queries, using Left join between the two tables. In the first query, consider table1 as leftmost table; and table2 as leftmost in the second query.
Use Where <right table id> IS NULL to filter out rows where there is no matching entry in the rightmost table.
Use Union to combine the resultset. Since there will not be any duplicates (due to our query results), we can use Union All.
Try the following:
SELECT t1.id, t1.value1, t1.value2, t1.value3,
t2.value4, t2.value5, t2.value6
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.id = t1.id
WHERE t2.id IS NULL
UNION ALL
SELECT t2.id, t1.value1, t1.value2, t1.value3,
t2.value4, t2.value5, t2.value6
FROM table2 AS t2
LEFT JOIN table1 AS t1 ON t1.id = t2.id
WHERE t1.id IS NULL

Difference between [table1.column1=table2.column1] and [table1.column1=1 AND table2.column1=1]

I don't know if there are any terms for these statements:
I have table1 and table2
table1
id link_id
1 1
1 2
1 3
table2
id link_url
1 www.a
2 www.b
3 www.c
And two different MYSQL Statements:
SELECT table1.id as id, table2.link_url as link_url FROM table1, table2 WHERE table1.link_id =1 and table2.id=1
SELECT table1.id as id, table2.link_url as link_url FROM table1, table2 WHERE table1.link_id=table2.id
I understand that they both return the same results.
Is there any difference in using either of them or doesn't it matter at all?
Yes there is Difference.
First Statement Returns only one row as you have set table1.link_id=1 and table2.id=1
Second Statement will Return every row which have link_id value in table1 similar to id value table2
link_id=table2.id select all data of your table where both coloumn are same .But WHERE table1.link_id =1 and table2.id=1 select data where link_id is 1 and id is 1.... both are diffrent
But USE JOIN is good option :-
SELECT table1.id as id, table2.link_url as link_url
FROM table1 join table2
on table1.link_id=table2.id
WHERE table1.link_id =1

join query in mysql

i am having table structure like this
table1 table2
pid pname pid uid cat
1 a 1 1 1
2 b 1 2 1
3 c 1 3 1
select * from table1 as t1 LEFT JOIN table2 as t2 on t1.pid=t2.pid where t2.uid=1 AND t2.cat=1
it's select the two rows
i don't want to group pid because i may have same pid in table one so i need to get only number of rows matched with pid
This may be silly question but i tried hard i couldn't get anything .
I hope you people can help me!
Thanks in advance
If you want to get the count of rows that match:
SELECT COUNT(*)
FROM table1 t1 INNER JOIN table2 t2 on t1.pid = t2.pid
WHERE t2.uid=1
Your LEFT join is unnecessary, since you are filtering by table2.
http://en.wikipedia.org/wiki/Join_%28SQL%29