SQL find records based on two columns - mysql

Given a users table with primary key of id, I have a foreign table called friends which only has two fields (userid1, userid2). This allows us to create any kind of relationship between different users (one to many, one to one, etc). A user can appear in either column and both columns are equal. IOW, a single entry per relationship.
How can I pull all of the friends that a given user id has. Say Jonny, has 3 friends and his user id is 16... should my sql query look like this?
SELECT *
FROM db.users
JOIN db.friends
ON db.users.id = db.friends.userid1
AND db.users.id = 16
Hopefully, this is clear. Also, if possible, can I exclude Jonny from the result set?
This query, as listed gies me the following:
id name uuid birthday userid1 userid2
16 jonny ABCDEFGHIJKLMNOP 1967-04-27 01:00:00 1 2
16 jonny ABCDEFGHIJKLMNOP 1967-04-27 01:00:00 1 3
This is pretty close, except I want his friends, not jonny
Thanks guys, so I got it to work thanks to you. Here is the final working query.
SELECT *
FROM db.users
WHERE db.users.id IN
(
SELECT db.friends.userid2 as id FROM db.friends WHERE db.friends.userid1 = 16
union
SELECT db.friends.userid1 as id FROM db.friends WHERE db.friends.userid2 = 16
)
which gives me:
id name uuid birthday
2 robin ABCDEFGHIJKLMNOP 1967-04-27 01:00:00
3 gary ABCDEFGHIJKLMNOP 1967-04-27 01:00:00

You could do a sub query like:
SELECT *
FROM users
WHERE id IN
(
SELECT userid2 as id FROM db.friends WHERE userid1 = 16
)

Add the condition for the user.id to your where clause at the end:
Select * From users
INNER JOIN friends on
users.id = friends.userid1
Where users.id = 16
Also, I would use an Inner Join which will return all records from users only where there is a match in friends

You should filter on the friends table, not the users table.
SELECT friends.*
FROM friends
INNER JOIN users
ON friends.userid2 = users.id
WHERE friends.userid1 = 16
If you just need the friend ID's then there is not reason to join at all
SELECT userid2
FROM friends
WHERE userid1 = 16

You need a list of friends ids:
SELECT U
FROM DB.USERS U
WHERE U.ID IN ( SELECT F.USERID2 FROM DB.FRIENDS F WHERE F.USERID1 = 16)

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)

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

Single Row Friendship Database Schema with getting userid from one column or the other

I need help querying the friendID from a table.
My table stores the user id of two members who are friends together.
But in order to store a "friendhship" b/w two members I would have to store two records like this:
friendshipID | userID | friendID
1 | 5 | 10
2 | 10 | 5
Yet, that seems heavy for the DB when we really only need to store the first record as that is sufficient as it contains both ids of both members.
However, the trouble comes when I want to query the records of the friends of ID=5. Sometimes the ID is in the userID column and other times it is in the friendID column.
This is the query I am using:
SELECT *
FROM friends
WHERE userID = '5'
OR friendID = '5'
But what I want to do is something like this
SELECT
if $userID=5 then userID as myfriend
else friendID=5 then friendID as myfriend
FROM friends WHERE userID='5' OR myfriendID='5'
Hope that makes sense. In the end I would like to have all the friends ID's of member #5 and not bring up results with #5 as the friend or user....but just his friends.
This query would return the Id value, and name, of the friends of #5 as shown in this SQL Fiddle Example
SELECT f.FriendId AS FriendId
, u.Name AS FriendName
FROM FriendTable AS f
INNER JOIN UserAccount AS u ON f.FriendId = u.UserId
WHERE f.UserId = 5
UNION
SELECT f.UserId AS FriendId
, u.Name AS FriendName
FROM FriendTable AS f
INNER JOIN UserAccount AS u ON f.UserId = u.UserId
WHERE f.FriendId = 5
The UNION will remove duplicates, making this query work for both a single record of friends, or the 2 record friendship you mention in the comment. You shouldn't need the 2 record friendship though, because there is no new information being stored in the second record that you cannot get from only having one record.

Mysql join query

I have table users and another table premium_users in which I hold the userid and the date when he bought premium membership.
How can I use mysql join , so that in a single query I can select all the columns from the table users and also know for each premium user the date he joined on.
USERS:
ID USERNAME
1 JOHN
2 BILL
3 JOE
4 KENNY
PREMIUM USERS:
ID USERID DATE
1 2 20/05/2010
2 4 21/06/2011
And the final table (the one that will be returned my the query) should look like this:
ID USERNAME DATE
1 JOHN
2 BILL 20/05/2010
3 JOE
4 KENNY 21/06/2011
Is it ok for some rows to have the DATE value empty?
How can I check if that value is empty? $row['date']=='' ?
EDIT:
This was only an example, but the users table has much more columns, how can I select all from users and only date from premium_users without writing all the columns?
select u.*, pu.DATE
from USERS u LEFT OUTER JOIN PREMIUM_USERS pu on
u.ID = pu.USERID
You can check if a row is empty with:
if (!$row['DATE'])
{
...
}
select USERS.ID, USERS.USERNAME, PREMIUM_USERS.DATE
from USERS
join PREMIUM_USERS on USERS.ID = PREMIUM_USERS.ID
order by USERS.ID
This is mssql syntax, but it should be pretty similar...
select *
from users u
left join premiumUsers p
on u.id = p.id
order by u.id asc
SELECT A.*, B.DATE
FROM USERS A
LEFT JOIN PREMIUIM_USERS B on A.ID=B.USERID
EDITED
It might be easier to have it all in one table. You can have nullable fields for isPremium(t/f) and premiumDate. you actually dont even need the isPremium field. just premiumDate if its null they are not premium and if it has value they are premium user and you have the date they joined.

MySQL inner join with 2 columns

I have one table users with 2 fields : id , name and another table friends with 2 fields : userid1 userid2 .
So this means userid1 is friend with userid2 . I want , with one inner or left join to show this :
userid1 name(got from users table) is friend with userid2 name(got from users table)
something
SELECT * FROM friends INNER JOIN users ON friends.userid1 = users.id AND friends.userid2 = users.id but this is not working.
Any good query with good explanation please?
If, for example I have the next details in the users table :
ID : 1 NAME : FinalDestiny
ID : 2 NAME : George
and the next details in the friends table :
ID1 : 1 ID2 : 2
So this means 1 is friend with 2.
I need with one query to get the name of 1 and the name of 2 and to echo that they're friends
FinalDestiny is friend with George
I know that you specify that you want this done with one join, but it looks to me like you need two. I believe this query will give you what you need:
SELECT u1.Name, u2.Name
FROM Users u1, Users u2, Friends f
WHERE u1.id = f.userid1 AND u2.id = f.userid2
I am joining the Users table with the Friends table with on Users.id = Friends.userid1. Then, I am joining this new table with the Users table on (new table).userid2 = Users.id. This results in a table with 4 columns. These columns are the original 2 columns of the Friends table in addition to 2 columns for the names of the friends. u1, u2, and f and referring to the three tables that were joined. The users table was joined with the friends table twice. u1 is the copy of the Users table that was joined on Friends.userid1 = User.id. u2 is the copy of the Users table that was joined on Friends.userid2 = User.id.
From this table with 4 columns, I am selecting only the names of the friends.
Let me know if more explanation is needed.
You check on a user being a friend of itself. Use OR in your select to match user's friends:
SELECT * FROM friends INNER JOIN users ON friends.userid1 = users.id OR friends.userid2 = users.id
If, for example I have the next details in the users table :
ID : 1 NAME : FinalDestiny
ID : 2 NAME : George
and the next details in the friends table :
ID1 : 1 ID2 : 2
So this means 1 is friend with 2.
I need with one query to get the name of 1 and the name of 2 and to echo that they're friends
FinalDestiny is friend with George