How to get two tables data using single mysql query? - mysql

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

Related

mysql query that does not return an id with multiple entries

I wasn't sure how to word the title, but here is what I am trying to do. I have a table where the id can have multiple entries
id | number
___________
1 | 90
1 | 88
2 | 88
3 | 88
I want a query that will return all ids that don't contain the number 90, so only 2 and 3 in this example. I have tried the below, but it still returns the id of 1 since it also has a number of 88.
SELECT DISTINCT id FROM table WHERE number NOT IN (90)
One way of getting the result is by using NOT EXISTS. Basically what it does it it gets all ID which has 90 in the inner query and the NOT EXISTS only shows all ID not in the inner query.
SELECT A.*
FROM TableName a
WHERE NOT EXISTS (SELECT NULL
FROM TableName B
WHERE a.ID = b.ID
AND b.number = 90)
Here's a Demo.
An alternative is by using LEFT JOIN which yields the same result as above.
SELECT a.*
FROM TableName a
LEFT JOIN TableName b
ON a.ID = b.ID
AND b.number = 90
WHERE b.id IS NULL
Here's a Demo.
You can use subquery:
SELECT id
FROM table
WHERE id NOT IN (SELECT id FROM table WHERE number = 90)
You can use aggregation as illustrated below for better performance:
SELECT ID
FROM YourTable
GROUP BY ID
HAVING NOT INSTR(GROUP_CONCAT(`number`),'90');
Demo on SQL Fiddle.

Select statement with where clause subquery returning multiple rows to be checked if contained in another subquery

This is roughly what I have been trying to do and I can not seem to figure out how to get it to work.
SELECT a.name FROM tableA a, TableB b
WHERE a.key = b.key
AND (SELECT b.values FROM tableA a, TableB b
WHERE a.key = b.key
AND a.name = Prime_Key) IN
(SELECT b.values FROM tableA a, TableB b WHERE a.key = b.key)
I have two tables with a one to many relationship from tableA to tableB. I need a select that find all the values from tableB for a specific name in tableA and then finds all the names that also are associated with all the values. So the final output will be a list of names that have a link to all of the values that the given Prime_Key has.
A bit of sample data would be:
tableA:
name key
Bob 1
Alice 2
Mark 3
Jill 4
Luke 5
and tableB:
key value
1 short
1 boy
2 tall
2 girl
2 blond
3 short
3 brownhair
3 boy
3 golf
4 girl
5 golf
5 boy
5 brownhair
So if I were to replace Prim_Key with Bob, the results would be Markas he has both values short and boy. Likewise if Prim_Key was Mark there would be no return as no one else has all the values that he does
You can use subquery joins + counting matches to achieve your results:
SELECT
person_name,
sum(total_match) total_matches,
num_attributes
FROM (
SELECT
search_name,
search_value,
num_attributes,
person_name,
sum(is_match) total_match
FROM (
SELECT
search_subject.name as search_name,
search_subject.value as search_value,
search_subject.total_attributes as num_attributes,
people.name as person_name,
people.value as person_value,
IF(search_subject.value=people.value,1,0) as is_match
FROM (
SELECT
name,
value,
total_attributes
FROM tablea
JOIN tableb USING(`key`)
JOIN (
SELECT count(*) total_attributes
FROM tablea
JOIN tableb using(`key`)
WHERE name = 'Bob'
) attributes_count
WHERE name = 'Bob'
) search_subject
JOIN (
SELECT
name,
value
FROM tablea
JOIN tableb using(`key`)
) people ON ( search_subject.name <> people.name)
) x
GROUP BY search_name, search_value, person_name
) y
GROUP BY person_name
HAVING total_matches = num_attributes
Firstly, I used GROUP_CONCAT function to group values for each key into one and, at the mean time, created the pattern for like clause.
SELECT key,
GROUP_CONCAT(VALUE ORDER BY VALUE DESC SEPARATOR '%' ) AS myValues
FROM tableB
GROUP BY key;
The result would be sth like this:
key value
1 boy%short
2 blond%girl%tall
3 boy%brownhair%golf%short
4 girl
5 boy%brownhair%golf
Then create the like query to get the result. For simplicity, you can create a view using:
CREATE VIEW table_ab AS (SELECT key, GROUP_CONCAT(VALUE ORDER BY VALUE DESC SEPARATOR '%' ) AS myValues
FROM tableB
GROUP BY key);
Finally you can get the result by:
SELECT
t2.name
FROM
table_ab t1
LEFT JOIN test_a t2
ON t1.key = t2.key
WHERE t1.myvalues LIKE
(SELECT myvalues FROM table_ab WHERE key = (SELECT key FROM test_a a WHERE a.name = 'Bob')) AND t2.name != 'Bob'

Retrieve data using joins with multiple conditions

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
);

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

MySQL join multiple columns from same table

I am trying to write a query that returns a users profile information, along with a count of occurrences of the user's ID in 2 columns from another table. An example below:
TableA
userID userName
1 UserA
2 UserB
TableB
LinkID leadID followID
1 1 2
2 1 3
3 2 1
Querying against UserID 1 I would expect to retrieve UserA, 2 (occurences of 1 in leadID), and 1 (occurences of 1 in followID). Any help with this is much appreciated, and thanks in advance.
You don't actually need to join for this - you can instead make three separate selects.
SELECT
(
SELECT userName
FROM TableA
WHERE userID = 1
) AS userName,
(
SELECT COUNT(*)
FROM TableB
WHERE leadID = 1
) AS count_leadID,
(
SELECT COUNT(*)
FROM TableB
WHERE followID = 1
) AS count_followID
Result:
userName count_leadID count_followID
UserA 2 1
SELECT a.userName,
SUM(IF(b.leadId = a.userId, 1, 0) as Leads,
SUM(IF(b.followId = a.userId, 1, 0) as Follows
FROM TableA a
TableB b
GROUP BY a.userName
SELECT a.userName,
b1.count(*) as leads,
b2.count(*) as follows
FROM TableA a
INNER JOIN TableB b1 on a.userID = b1.leadID
INNER JOIN TableB b2 on a.userID = b2.followID
GROUP BY a.userName
Depending on how mySQL optimizes and if you have an index on leadID and followID then this could speed up the query, especially if you're going to query just a few users rather than them all at the same time.