SELECT query on multiple table - mysql

I have two tables,
ID NAME
-------------------
12 Jon Doe
4 Jane Doe
9 Sam Doe
AND
MemID Cat# DateChkOut DateDue DateRet
4 T 430.98 1956 15-Mar-2011 14-Jun-2011 31-May-2011
12 B 125.2 2013 15-Mar-2011 14-Jun-2011
4 T 430.98 1956 27-Dec-2012 25-Mar-2013
Now I need to list the `members’ names who have never checked out a book.
SELECT Name FROM MEMBER, CHECKOUT WHERE ID != MemID;
did not work. Any suggestions?

You need to use a LEFT JOIN in this case.
Try the following:
SELECT M.Name
FROM MembersTable M
LEFT JOIN CheckoutTable C On C.MemId = M.ID
WHERE C.MemId IS NULL
Edit:
LEFT JOIN works in this situation because it joins the two tables on a common key - in this case the MemId. Since this is a LEFT JOIN it will take everything that exists in the Left table (Members) and if a match is found, it will include everything on the Right table (Checkout). But if no match is found in the Checkout table, everything on that side will be NULL.
So, all you would need to do is check to see if the Right side is NULL.
Hope this makes sense :)

SELECT name FROM member WHERE id NOT IN (SELECT MemID FROM checkout)
I think it should do the job

Use a correlated subquery with NOT EXISTS.
SELECT Name
FROM MEMBER a
WHERE NOT EXISTS(SELECT 1 FROM CHECKOUT b WHERE b.MemID = a.ID)
See Optimizing Subqueries with EXISTS Strategy.

If you use NOT IN in the query, that can be slow for large queries, try instead following using JOIN, which will be way faster:
SELECT MEMBER.NAME FROM MEMBER
LEFT JOIN CHECKOUT ON CHECKOUT.MemID = MEMBER.ID
WHERE CHECKOUT.MemID IS NULL:

Because you may want more fields returned an outer join is good method of accomplishing this.
SELECT Name
FROM MEMBER M
LEFT JOIN CHECKOUT C
on M.ID = C.MemID
WHERE C.MemID is null;

Try this:
SELECT M.ID,M.Name
FROM MEMBER M LEFT JOIN
CHECKOUT C ON C.MemID=M.ID
WHERE C.DateRet IS NULL
It will select the user details whose DateRet is null.
Sample result:
ID NAME
-------------------
12 Jon Doe
4 Jane Doe

You have to use a where in and check for the DateChkOut:
SELECT Name
FROM MEMBER
WHERE ID not in
( select MemID
from CHECKOUT
where DateChkOut is not null
)

SELECT id,
name
FROM Member
WHERE id NOT IN
(SELECT memid
FROM checkout)
or
SELECT id,
name
FROM member m
LEFT OUTER JOIN checkout c ON m.id = c.memid
WHERE c.memid IS NULL

Related

Return the Inverse of Tuples from an INNER JOIN Query

I am trying to get the remaining tuples from a query. In this case, course_id 3 and 4 from courses because the user admin# has NOT taken these (they've only taken 1 and 2). The tables are already joined nicely and queries are working when I try a LEFT JOIN ...
select course_name from courses LEFT OUTER JOIN users_courses ON users_courses.user_course_id = courses.course_id where users_courses.user_email = "admin#---.com";
But this returns the courses 1 and 2, not 3 and 4
you could do another thing by getting all of the courses that is not exists in the courses list for this user like this
select course_name from courses where course_id not in (select user_course_id from users_courses where user_email = 'admin#....')
update
forget to add the column name course_id
Ah! I misunderstood what you were after. Joseph's method will work, but, as a rule, you should try to avoid "in(select...".
To knock-out the courses the admin has taken, just add a null condition:
select course_name from courses LEFT OUTER JOIN users_courses
ON users_courses.user_course_id = courses.course_id
and users_courses.user_email = "admin#---.com"
where users_courses.course_id is null;

MySQL Left Join with child IsDeleted Flag

I have been searching google, but can't seem to exactly figure out my case. What I am trying to do is join a customer who has a list of jobs associated to him. I want the customer and any "active" jobs, in other words they haven't been deleted. The deleted flag is whether or not the datedeleted column is null or not.
So Lets say I have a table Customer:
ID - Name
1 - Joe Blow
2 - John Smith
And I also have a table of Jobs
ID - CustomerId - Name - DateDeleted
1 - 1 Build Fence NULL
2 - 2 - Clean Yard - 25/12/2014
What I want to do is get a customer with a list of their jobs. Now I know that if I do a join with Jow Blow it works fine, but it doesn't work when I want to get John Smith, it doesn't return any rows because I am checking the Deleted flag which then doesn't return any rows for jobs which in turn doesn't return any customer.
SELECT c.id, c.name, j.name as JobName from customer c
left join job j on c.id = j.CustomerId
where c.id = :id AND j.date_deleted IS NULL
And I want a results to be either:
Id - Name - JobName
1 - Jow Blow - Build Fence
or
Id - Name - JobName
2 - John Smith - NULL
Any help would be greatly appreciated. Thanks!
The problem is in your WHERE clause. When you add the AND j.date_deleted IS NULL, you are turning your OUTER JOIN into an INNER JOIN. You will need to move this condition to the ON clause of your OUTER JOIN.
Use this instead:
Select c.id,
c.name,
j.name As JobName
From customer c
Left Join job j On c.id = j.CustomerId
And j.date_deleted IS NULL
Where c.id = :id
Just try with this approach.As per my understanding you want to show all those jobs which has no date.
select e.Id,e.Name,( case when j.date is null then j.name else null end) as Jobprocess from
customer e
left join job j on e.Id=j.custId

Multiple joins into one column

I have query that LEFT joins information from two tables. With code with following joins
LEFT JOIN A on source = news_id
LEFT JOIN B on source = other_news_id
How can join or display data from the two columns so it produces one column information.
ID source Left Join on ID a Left Join on ID b
a 1 info1 <null>
a 2 info2 <null>
b 3 <null> info3
b 4 <null> info4
Something along the lines of
ID source info
a 1 info1
a 2 info2
b 3 info3
b 4 info4
How can I bring all left joins into one column?
You can use COALESCE() if there will always only be one value. It returns the first non-null argument.
SELECT ID, source, COALESCE(infoa, infob) AS info FROM ...
The COALESCE function will do this.
See the MySQL documentation for examples of how to use this function.
From the sample data, it seems that no A.news_id is never equal to a B.other_news_id and the two columns you want to COALESCE have at least one NULL value.
I also guess your FROM clause is something like this:
FROM T
LEFT JOIN A on T.source = A.news_id
LEFT JOIN B on T.source = B.other_news_id
If that's the case, you could also rewrite the query with a UNION:
SELECT ID, source, infoa AS info
FROM T
JOIN A on T.source = A.news_id
WHERE ...
UNION ALL
SELECT ID, source, infob
FROM T
JOIN B on T.source = B.other_news_id
WHERE ...
If I understand you correctly, you need to use INNER JOINs instead of LEFT JOINs

Select query with MySQL database where distinct member id with least registration time are to be selected... How can I do it?

I am trying to work on a query where my database schema looks like:
MEMBER TABLE
member_id----------member_name--------member_nickname
1 prashant prash
2 christopher chris
3 nick nick
4 harvey harvey
----------------------------------------------------------
CHECKIN TABLE
checkin_id------------------member_id------------------reg_on
1 1 1287713712
2 1 1287723999
3 2 1287733712
4 1 1287735912
5 3 1287803712
6 2 1287833712
Now when I select distinct users, I want to join both tables to see the following result:
member_id----------------member_name---------------reg_on
1------------------------------prashant -----------------1287713712
2------------------------------christopher---------------1287733712
3------------------------------nick------------------------1287803712
Please Help!!!
Edit Don't know what I was thinking by overcomplicating my previous answer...
This is a simple JOIN with an aggregate:
SELECT
m.member_id,
m.member_name,
MIN(c.reg_on) AS reg_on
FROM
MEMBER m JOIN CHECKIN c ON m.member_id = c.member_id
GROUP BY m.member_id, m.member_name
If you select and group by the checkin table, that will give you the data you want, then join to the member table to fill out the rest of the query.
SELECT c.member_id, m.member_name, MIN(c.reg_on) AS reg_on
FROM checkin c
JOIN member m ON m.member_id = c.member_id
GROUP BY c.reg_on
ORDER BY c.member_id;
No subselect necessary.

Joining Tables in MySQL

I have two tables namely Students & Hobbies with following structure and records:
ID,Name
-----------
9,Peter
10,Steve
ID,Hobby
-----------------
9,dancing
9,singing
10,learning
I want to JOIN these tables and get a unique record from table Students.
I am doing this right now which evolves duplicate records:
SELECT a.Name
FROM Students a
LEFT JOIN Hobbies h ON a.ID =h.ID
This gives :
Name
----------
Peter
Peter
Steve
I got the reason, this is because, the table Hobbies has two records of ID=9 , that is why duplicate records are evolved, but how to retrieve a single record? Please help.
I want this:
Name
-----------
Peter
Steve
SELECT a.ID, a.Name
FROM Students a
LEFT JOIN Hobbies h
ON a.ID = h.ID
GROUP BY a.ID, a.Name
With the GROUP BY, you could then answer questions like "How many hobbies does each student have?"
SELECT a.ID, a.Name, COUNT(*) AS Number_of_Hobbies
FROM Students a
LEFT JOIN Hobbies h
ON a.ID = h.ID
GROUP BY a.ID, a.Name
This is really not the way a JOIN should be used.
left joining an unreferenced table on a constant gets you nothing.
the answer to the question you asked is "use a DISTINCT clause":
SELECT DISTINCT a.Name FROM Students a LEFT JOIN Hobbies h ON a.ID = 9
...but really, I'm pretty sure this is not what you want to do.
based off the comments, I believe what the OP's intent was something like this:
SELECT
a.Name
FROM
Students a
WHERE
a.ID = <Student ID>;
... AND , for the hobbies reference:
SELECT DISTINCT
a.ID,
a.Name
FROM
Students a
INNER JOIN
Hobbies h ON h.ID = a.ID
WHERE
h.Hobby = <Hobby Name>;
Use the distinct keyword:
SELECT distinct a.Name
FROM Students
etc....
It eliminates duplicate rows, so you'll only get one of each name.
You are getting duplicates because Peter has 2 hobbies. If you want a single record per User do this:
select * from Student where Id in (
Select DISTINCT Id from HobbY)