Retrieve data using joins with multiple conditions - mysql

I am trying to write a query which retrieves data from a table which doesn't have data on another table.
I have table A with values
ID StudentID CLASSID
1 1 2
2 2 3
3 3 4
4 4 5
TABLE B with values
ID StudentID CLASSID
1 1 2
2 2 3
I am trying to return values from table A with ID 3,4 which is not available in TABLE B.
Query I have tried is
SELECT *
FROM A AS a
WHERE NOT EXISTS
(
SELECT *
FROM B AS b
WHERE a.student_id = b.student_id
AND a.CLASSID = b.CLASSID
);
NOTE: As my problem was slow query. I have fixed this problem by creating index which made this query run fast.
Thanks for your effort.

Using LEFT OUTER JOIN
SELECT TableA.* FROM TableA
LEFT OUTER JOIN TableB
ON TableA.ID = TableB.ID
WHERE TableB.ID IS null
Using NOT IN
SELECT * FROM TableA
WHERE TableA.ID NOT IN ( SELECT ID FROM TableB)
Using NO EXISTS
SELECT *
FROM tableA a
WHERE NOT EXISTS
(
SELECT 1
FROM tableB b
WHERE a.studentsID = b.studentsID
AND a.CLASSID = b.CLASSID
);

Related

MySQL find ids when match other table or not exists in it

I have two tables and I want a query to show records from one table that match the second table or doesn't exists at all. In other words if the record exists in table B and does not match the condition don't show it.
TABLE A TABLE B
ID VAL ID AID BVAL
--------- ----------------
1 v1 1 2 B1
2 v2 2 3 B2
3 v3
I've tried with this query:
SELECT ta.id, ta.val, tb.bval
FROM table_a ta
LEFT JOIN table_b tb ON ta.id = tb.AID AND tb.BVAL = 'B1'
the goal is to get ONLY this rows:
ID VAL BVAL
------------------
1 v1 NULL
2 v2 B1
But obviously with this query I get all Table A.
Thanks for your time!
I have found a solution, I post it in case someone else is having the same issue.
SELECT ta.id, ta.val, tb.bval
FROM table_a ta
LEFT JOIN table_b tb ON ta.id = tb.AID
GROUP BY ta.id, ta.val, tb.bval
HAVING tb.BVAL = 'B1' OR tb.BVAL IS NULL

SQL to fetch data where Unique key matches but the data is different in some other columns between different tables

I have two tables of same structure as below. I am trying to write a query to compare both the tables using the Unique key which is the first column and trying to return values when there is a mismatch in the second column.
If the key is not present then no need to consider that data. only if the key is present in both the table then we have compare it.
Table A
ColumnA ColumnB
A 1
B 2
C 2
D 8
Table B
ColumnC ColumnD
A 1
B 3
C 5
F 4
For example the output of the above table when comparing Table A with B should be
B 2
C 2
and when comparing Table B with A it should be
B 3
C 5
Ideally the difference in the base table should come.
I have tried Joins and Unions but I am not able to fetch the data as mentioned above.
Since you want only those rows which has matching FK values in both the tables, we simply need to use INNER JOIN.
Now, we can simply consider the unmatching rows by using WHERE .. <> ..
When comparing Table A against Table B, we can get Table A rows only:
SELECT
tA.*
FROM tableA AS tA
JOIN tableB AS tB
ON tB.ColumnC = tA.ColumnA
WHERE tB.ColumnD <> tA.ColumnB
When comparing Table B against Table A, simply fetch the rows from Table B only:
SELECT
tB.*
FROM tableA AS tA
JOIN tableB AS tB
ON tB.ColumnC = tA.ColumnA
WHERE tB.ColumnD <> tA.ColumnB
I would do :
SELECT t.*
FROM tablea t
WHERE EXISTS (SELECT 1 FROM tableb t1 WHERE t1.cola = t.cola AND t1.colb <> t.cold);
Same would be for second version just need to swipe the table names.
use EXISTS and union all
SELECT t.*
FROM tablea t
WHERE EXISTS (SELECT 1 FROM tableb t1 WHERE t1.cola = t.cola AND t1.colb <> t.colb)
union all
SELECT t.*
FROM tableb t
WHERE EXISTS (SELECT 1 FROM tablea t1 WHERE t1.cola = t.cola AND t1.colb <> t.colb)

How can I select tableB_name from tableB and join into tableA in mysql?

I have 2 tables here:-
Table A
tableA_id
tableB_id1
tableB_id2
tableB_id3
Table B
tableB_id
tableB_name
how can I join these 2 tables into 1 single result and return result like:-
tableA_id tableB_id1 tableB_name1 tableB_id2 tableB_name2 tableB_id3 tableB_name3
** tableB_name in 1,2,3 will base on value in tableB_id1,2,3
Thank you.
You would need to join tableb 3 times with tablea according to your current structure
select a.tableA_id,
b1.tableB_id tableB_id1,
b1.tableB_name tableB_name1,
b2.tableB_id tableB_id2,
b2.tableB_name tableB_name2,
b3.tableB_id tableB_id3,
b3.tableB_name tableB_name3
from tablea a
join tableb b1 on a.tableB_id1 = b1.tableB_id
join tableb b2 on a.tableB_id2 = b2.tableB_id
join tableb b3 on a.tableB_id3 = b3.tableB_id
Your current schema is restricted to 3 references to tableb, what if you need another one. If there is a many to many relation between these 2 tables i suggest you to restructure your table and include a junction table to relate these tables
tableab_pivot
tablea_id tableb_id
1 6
1 7
1 8

How to get two tables data using single mysql query?

Following is my tables which is student id is common field in both tables. I want to get both tables data in single query.Also get recent data of student.
table A:
student_id name surname email
------------------------------------------------
1 ABC LLL abc#gmail.com
2 PQR SSS pqr#gmail.com
Table B:
student_id Assignment_Id Assignment_Name last_submited
---------------------------------------------------------------------
2 1 asign_1 sub_0001
1 2 asign_2 sub_0002
2 3 asign_2 sub_0003
I want exact output like:-
student_id Assignment_Id email last_submited
--------------------------------------------------------------
2 3 pqr#gmail.com sub_0003
I have used following query for getting recent record but confused how to get email id along with this.
SELECT assignment_id,
student_id,
last_submited
FROM tableB
WHERE student_id= '2'
ORDER BY assignment_id DESC LIMIT 1
You can make use of a JOIN
select tableB.assignment_id,
tableB.student_id,
tableB.last_submited,
tableA.email
from tableB INNER JOIN
tableA ON tableB.student_id = tableA.student_id
where tableB.student_id= '2'
order by tableB.assignment_id desc
limit 1
INNER JOINs are used to return data where the data is in both tables (so en entry would exist in tableA and tableB).
LEFT JOINs are used when you wish to retrieve all data from tableA and those values that are available in tableB.
So, lets say you had
TABLEA
-------
1
2
and
TABLEB
-------
1
SELECT *
FROM TABLEA INNER JOIN
TABLEB ON TABLEA.ID = TABLEB.ID
would return
1,1
Whereas
SELECT *
FROM TABLEA LEFT JOIN
TABLEB ON TABLEA.ID = TABLEB.ID
would return
1,1
2,NULL
You need to use join
SELECT a.student_id,
b.Assignment_id,
a.email,
b.last_submitted
FROM a
INNER JOIN b ON a.student_id = b.student_id
WHERE a.student_id= '2'
ORDER BY b.assignment_id DESC LIMIT 1
Join both the tables,
SELECT B.assignment_id,
B.student_id,
A.email_id ,
B.last_submited
FROM tableB 'B',
tableA 'A'
WHERE B.student_id= '2'
AND A.student_id=B.student_id
ORDER BY assignment_id DESC LIMIT 1

mysql left join returns unexpected amount of rows

I have 2 tables where
tableA has 41 rows
and
tableB has 3 rows
I am trying to get the total rows of these 2 tables via a query using left join but i get way more rows(123) than expected(44)
query:
SELECT COUNT(*)
FROM tableA as u
LEFT JOIN tableB as d
ON u.uid=d.uid
WHERE
u.uid=912391178669
AND
u.deleted = 0
AND
d.deleted=0
tables schema:
tableA
id | uid | deleted
tableB
id | uid | deleted
I have run the following query It is working correctly.. U can check it out.
SELECT
( SELECT count(*) from table1 where.... )
+ ( SELECT count(*) from table2 where.... )
as total from dual
I'm guessing that you have three rows in tableA with the uid given in the query. That will mean that each row in tableA will join once with each row in tableB, which means you will back 41 x 3 rows or 123.
From the number of rows you are expecting back, I wonder if you need a Union instead of a join.
Select * from tableA where uid = 912391178669 and deleted = 0
union all
Select * from tableB where uid = 912391178669 and deleted = 0
A union will combine the results of two queries. A join will combine the columns of table tables in a single query.
41*3=123
each row of TableA has uid=912391178669 and tableB each row also have uid that's why you are getting 123 row total. use some filter criteria to get desired result (like some AND condition)
if you can show us your table column then it may be possible to help you .
Left join does not combine the rows of two table .
TableA left join TableB will give you all the row of table A meeting the joining condition.
SELECT COUNT(*)
FROM tableA as u
LEFT JOIN tableB as d
ON u.uid=d.uid
AND
u.deleted = d.deleted
WHERE
u.uid=912391178669
AND u.deleted = 0
SELECT SUM(
(SELECT count(*) from tableA WHERE uid=912391178669)
+ (SELECT count(*) from tableA WHERE uid=912391178669)
) as totalRows