MySQL Left Join with multiple rows - mysql

I'm looking to join a 2 tables but the second table has a one to many relation. Can I omit the entire row if any of the lines have a certain value? Let me explain more.
User table
id name email
1 bob bob#test.com
2 foo foo#test.com
Music table
id userId
1 1
1 2
2 1
3 1
2 2
Say I don't want it to show the user if he has a relation to music table id 2. Also looking for distinct user.
If I try something like this it will still show both users.
SELECT * FROM users u LEFT JOIN music m ON u.id = m.userId WHERE m.id <> 3
I want it to check all the rows and if it has the id 3, it won't show. I hope I made sense. Thanks a lot.

Try using sub query like this:
SELECT * FROM users
WHERE id NOT IN (SELECT userId FROM music WHERE id=3)
This query means to select all users if their id is not related with music.id 3.

Related

How to JOIN SELECT from multiple tables, where the SELECTS is based on different conditions?

I have three tables. One with notes Notes, one with users Users, and one a relational table between users and notes NotesUsers.
Users
user_id first_name last_name
1 John Smith
2 Jane Doe
Notes
note_id note_name owner_id
1 Math 1
2 Science 1
3 English 2
NoteUsers
user_id note_id
1 1
2 1
2 2
2 3
Hopefully, from the select statement you can tell what I'm trying to do. I am trying to select the notes that user_id = 2 has access to but doesn't necessarily own, but also along with this I'm trying to get the first and last name of the owner.
SELECT Notes.notes_id, note_name
FROM Notes, NotesUsers
WHERE NotesUsers.note_id = Notes.note_id AND NotesUsers.user_id = 2
JOIN SELECT first_name, last_name FROM Users, Notes WHERE Notes.owner_id = Users.user_id
My problem is that because the WHERE clause for first_name, and last_name versus that for notes are different, I don't know how to query the data. I understand that this is not how a JOIN works and
I don't necessarily want to use a JOIN, but I'm not sure how to structure the statement, so I left it in there so that you can understand what I'm trying to do.
You can join Notes with NoteUsers to check for access and with Users to add the user's details to the result:
SELECT n.noted_id, n.note_name, u.first_name, u.last_name
FROM Notes n
JOIN NoteUsers nu ON n.noted_id = nu.note_id AND nu.user_id = 2
JOIN Users u ON n.owner_id = u.user_id
you need here to use a query inside the main query. MySQL will return first all the note_id that the user with user_id = 2 has access to from NoteUser, then well build the outer query to return the first_name and the last_name of the owner.
SELECT u.first_name, u.last_name, n.note_name, n.note_id
FROM Notes AS n
LEFT JOIN Users AS u ON u.user_id = n.owner_id
WHERE n.note_id IN
(SELECT nu.note_id FROM NoteUser WHERE nu.user_id = 2)

Select all records from table A, even if one or more of it's ID(i.e FK) not present in table B

First of all, I know heading sounds a bit confusing and I am sorry for that. I couldn't find words to articulate myself exactly in a sentence.
So here is what I am trying to do :
A simple search box where user types in a name and gets autosuggestion like in google.
My first table('users') is like this :
Table 'users':
Id(PK) name email
10 max max#max.com
20 john john#john.com
30 jack jack#jack.com
40 jill jill#jill.com
And second table('pictures') like this :
Table 'pictures':
Id user_id(FK) profilepic iscurrent
1 10 abc.jpg 1
2 20 sds.jpg 0
3 30 asdasd.jpg 1
4 20 sdsdff.jpg 1
Now when users start typing name say "joh", he will see "john + john's email + john's picture" in suggestions .
This is how I am implementing it now :
SELECT users.name, users.email, pictures.profilepic
FROM pictures
INNER JOIN users
ON pictures.user_id=users.id
WHERE pictures.is_current = 1
AND users.name LIKE '%joh%' OR email LIKE '%joh%'
ORDER BY users.id
ASC LIMIT 5;
The problem is that it selects only records which have a FK in second table('pictures')
but I want users to see all records matching the name they entered even if that user doesn't have a profile picture .
Hope you've understood the problem.
Thanks in advance.
You should do a select from the users to the pictures using the left join instead of inner join. It should look like this:
SELECT users.name, users.email, pictures.profilepic
FROM users
LEFT JOIN pictures
ON pictures.user_id=users.id
WHERE pictures.is_current = 1
AND users.name LIKE '%joh%' OR email LIKE '%joh%'
ORDER BY users.id ASC
LIMIT 5;
Or, you leave it like that but use right join instead.
SELECT users.name, users.email, pictures.profilepic
FROM pictures
RIGHT JOIN users
ON pictures.user_id=users.id
WHERE pictures.is_current = 1
AND users.name LIKE '%joh%' OR email LIKE '%joh%'
ORDER BY users.id ASC
LIMIT 5;
You should use left join instead of inner join, this will return you all the rows from the table: users. Even if a user doesn't have a picture will also be listed.

mysql query find sets which element match to another sets element

My tables are like below format
User table
> id username interest_ids
> 1 Ram 1,2,3
> 2 Suja 2,3,
> 3 Rahul 2,4,5,6
> 4 nipa 1,4,6
Interest Tables Like
id name
1 Music
2 Book
3 News
4 T.V watching
5 Song
6 Dancing
7 Game
now i want to search user who have same interest.
example Nipa is a user whose interest id are 1,4,6
and interest ids match with user Ram (id 1)and Rahul(id 3)
What is mysql query so i can fetch users who has similar interest id like nipa.
If your tables were normalised properly (WHICH THEY SHOULD BE! DO IT!) and you had a user_interests table that looked like this:
create table user_interests (
user_id integer,
interest_id integer
);
Then your answer would be:
select distinct username
from users u
inner join user_interests ui
on u.id = ui.user_id
where ui.interest_id in
(select ui2.interest_id
from users u2
inner join user_interests ui2
on u2.id = ui2.user_id
where u2.username = 'Nipa'
)
and u.user_name <> 'Nipa'
As it stands, mysql can't split strings without a lot of effort that would be better spent fixing the tables.
Here's an example

Getting Average based on distinct row in mysql

I have a table users containing the fields userID,age,gender and i have another table
name as click_info containing fields(id,userID,clickID) The enrty in the click_info table are as following
id userID dubID
1 1 2
2 1 2
3 1 2
4 2 2
5 2 2
6 3 2
7 4 2
Now I want the average age of all the users who clicked on dubID 2 and i am using the following query
SELECT DISTINCT `dub_clickinfo`.`userID`, `users`.`age` AS `average`, `users`.*
FROM `dub_clickinfo` INNER JOIN `users` ON dub_clickinfo.userId = users.userID
WHERE (dubID=2)
The above query gives the incorrect average it will include the duplicate userID (like it will include userID 1 three times,2 two times) as well.
Please suggest a query
Thanks In Advance !!
Give it a try ,there is a one to many relation so you need to use left join not inner ,and apply a group function on user's id
SELECT dub_clickinfo.userID, users.age AS average, users.* FROM dub_clickinfo
LEFT JOIN users ON dub_clickinfo.userId = users.userID WHERE (dubID=2)
GROUP BY users.userID
try this
SELECT avg(age) FROM users WHERE userID in (select distinct userID from dub_clickinfo where dubID ='2')

MYSQL join tables multiple times

I have a table, with rows of events, and each one has (amongst lots of other fields) addedbyuser, editedbyuser, deletedbyuser
There are INT, and refer back to the users table to a particular user.
I am able to join one of the fields (say addedbyuser) without any problems, how do i join the rest and reference them in php?
events table:
eventid addedbyuser editedbyuser deletedbyuser
1 1 2 3
users table:
id username
1 name1
2 name2
3 name3
So basically, I want to display the names of who added, edited and deleted the article, can I do this in one SQL query?
Something like this:
select
evn.eventid,
us1.username as addedbyuser,
us2.username as editedbyuser,
us3.username as deletedbyuser,
from events evn
join users as us1 on
evn.addedbyuser = us1.id
join users as us2 on
evn.editedbyuser = us2.id
join users as us3 on
evn.deletedbyuser = us3.id