MySQL - Complex query issue, multiple tables - php

I'm having a bit of trouble figuring out an SQL statement that I need to make.
I have 2 tables
Friends
===================================
friendfromid | friendtoid | request
===================================
Users
=================
userid | username
=================
I need to get the userid and username of each user that is my friend.
My id is either in the friendfromid or friendtoid depending on if I am requested the user or the user requested me.
So basically what needs to happen is the script needs to look at the friends table, get all the rows where my id is either friendfromid or friendtoid check that the request field is set to 1, take all the rows that fit that match then get the ids and usernames of each friendfromid or friendtoid which isn't mine.
For instance, if my id was 8 and the friends id was 9, let's say they requested me their id would be in the friendfromid field and my id would be in the friendtoid field, that means the script would take their id (9) and match it to that user in the users table.

This will give friends list with friend id and friend name:
SELECT u.userid , u.username
FROM Friends f
JOIN Users u
ON (( f.friendfromid ={the ID} AND friendtoid=u.userid)
OR ( f.friendtoid = {the ID} AND friendfromid=u.userid))
WHERE f.request = 1
Put {the ID}= user id whose friend list required.

Should be something like this:
SELECT *
FROM users
JOIN friends
ON friendfromid != userid
OR friendtoid != userid
WHERE request = 1
AND userid = {the ID}

Can't achieve in 1 query.
To get friendtoid with "my user ID" in friendfromid field:
SELECT b.friendtoid FROM Users a, Friends b WHERE request=1 AND friendfromid = a.userid
Vice versa for friendfromid.

Use a UNION query, joining to friends as below
SELECT username FROM user INNER JOIN friends ON (userid = friendfrom) WHERE friendto = {myid) AND request = 1
UNION
SELECT username FROM user INNER JOIN friends ON (userid = friendto) WHERE friendfrom = {myid} AND request = 1
Remember you need indexes on the friendto and friendfrom columns for performance

Related

How can I compare 2 tables in mysql and check the result

I have two tables, one of them is for friends of a person and another one is for channel member.
I want to check if one of my friends is one of the channel members. If so don't show his name, else show him.
$get_friend = "select * from friends where user_1_id='$user_id' AND friends_status=1";
$run_friend = mysqli_query($conn,$get_friend);
$select_members = "SELECT user_id from channel_members where channel_id='$channel_id'";
$run_members = mysqli_query($conn,$select_members);
Try this query :
select * from friends where user_1_id='$user_id' AND friends_status=1 AND user_2_id NOT IN(SELECT user_id from channel_members where channel_id='$channel_id')
This will select all your friends from friends table which are not a member of channel '$channel_id'
SELECT
friends.*
FROM
friends
LEFT JOIN channel_members
ON channel_members.channel_id = '$channel_id'
AND channel_members.user_id = friends.user_2_id
WHERE
user_1_id = '$user_id'
AND friends_status = 1
AND channel_members.channel_id IS NULL
You can use this query.
I added an excluding LEFT JOIN.
It will try to join the members of the channel who are your friends to the result, but by specifying channel_members.channel_id IS NULL in the where clause you are filtering those datasets out which really have a member in the channel - leaving you with only the friends who are not in the channel.

SQL query using LIKE and Union

I'm trying to generate a list of friends for users to invite to an event, however only if they're not already attending the event or have a pending invite request.
The way my friends system works, there are 3 columns in the table. userid1, userid2, and friendstatus. The user who sent the request goes into column 1(userid1), the user who received the request goes into column 2(userid2). Since the user creating the event could be in either column, I use the following query when adding friends to the event.
//this block is finding friends from column1
SELECT userid1 as friendID
FROM friends
WHERE userid2 = $myUsername AND friendstatus = 1
UNION
// this section is finding friends from column 2
SELECT userid2 as friendId
FROM friends
WHERE userid1 = $myUsername AND friendstatus = 1
I set the userid as friendID because this query generates a list which I then use checkboxes for (which the value is determined from)
However, once the event is created if users attending it want to add more friends, I need a way to pull their friends but only if those friends are not alread attending or have a pending request.
The column in my events table for users attending is called acceptedInvites and the column for pending requests is in inviteRequest.
So, here's the query that I can't get to work. If the userid is in the acceptedInvites or inviteRequest DO NOT select that value
//this section is finding friends from column1
SELECT
events.inviteRequest,
events.acceptedInvites,
friends.userid1 as friendID
FROM friends
LEFT JOIN events on
friends.userid1 NOT LIKE '%events.inviteRequest%' AND
friends.userid1 NOT LIKE '%events.acceptedInvites%'
WHERE friends.userid2 = $userid AND friends.friendstatus = 1
UNION
//this section is finding friends from column 2
SELECT users.userid2 as friendId
FROM friends
LEFT JOIN events on
friends.userid2 NOT LIKE '%events.inviteRequest%' AND
friends.userid2 NOT LIKE '%events.acceptedInvites%'
WHERE friends.userid1 = $userid AND friends.friendstatus = 1
For example:
friends table
columns are friend1, friend2 and friendstatus
(row 1) userid1:1 userid2:userid2 friendstatus:1
(row 2) userid1:3 userid2:1 friendstatus:1
-userid1 is friends with userid1 and userid3. As I stated above, the user in userid1
events table
columns used are acceptedInvites inviteRequests
(row 1) acceptedInvites: "1~2" inviteRequests : " "
-userid1 and userid2 are attending the event, no pending invites
Based on this, if userid1 wants to add more friends only userid3 will show up.
I think you meant the following:
events.inviteRequest NOT LIKE '%' + friends.userid1 + '%'
This would be better, but wouldn't be correct either. How are you separating userIds in your inviteRequest? Assuming they are comma-separated, the following condition returns false even though userid 3 is not in the list:
'23,35,35' NOT LIKE '%3%'
See my point? A trick to fix this is to add a comma to both sides of inviteRequest, then you'll have something like:
',23,35,35,' NOT LIKE '%,3,%' -- Note the commas around 3.
Hope it helps!

A complicated mysql join

Ok, I have this first table which has, among other things:
table 1: id | depID (every id has one depID)
Then, I have a second table where I have table 2: userID | depID (where an userID is associated with multiple depIDs in separate rows. Also, I have table 3 with userID | rankID (where an userID is associated with one rankID).
I need to get all id and depID from table 1, and then to check, which userIDs of table 2 shares the same depID (table1.depID = table2.depID), and then, to check which of those userIDs from table 2 has rankID = $rID
Thanks guys.
I think this SQL should get you what you want, but I'm not 100% clear from the wording of the question:
SELECT table2.userID
FROM table1
JOIN table2
ON table1.depID = table2.depID
JOIN table3
ON table2.userID = table3.userID
AND table3.rankID = $rID;

Best way to display listing of items of friends, that are hidden to everyone else, in php/mysql

I have a listing of items that are shown to everyone if the item is marked as status = 1
When items are added, their status could also be 0, which means they are invisible to everyone, unless you are friends with the user who submitted the item. Friendship userid pairs are stored in a different table.
Friends table is 3 columns: friends_inviter, friends_accepter, friends_status (if friends_status = 1 they are friends). User (their ID) who initiates the friendship is the inviter, user who accepts the friendship is the accepter. So your friends' IDs can appear in either column.
The items table (for this example) has 3 columns also: item_id, item_status, item_owner
What would be the best way to display the listing of status = 1 items, as well as status = 0 items, of users who are appearing in your friends list.
My proposition:
SET #userID = 1;
SELECT i.*
FROM items i
WHERE i.status = 1
OR (
i.status=0
AND
i.user_id IN (
SELECT f.inviter_id FROM friends f WHERE f.accepter_id = #userID AND f.status = 1
UNION
SELECT f.accepter_id FROM friends f WHERE f.inviter_id = #userID AND f.status = 1
)
)
[+] I haven't noticed your edit, but this requires your item's table to also have column to distinguish who have added this item
I made a few assumptions about your tables, like that each item had a foreign key to the user who posted the item.
select i.* from friends f
join items i on
(i.user_id = f.friends_inviter XOR i.user_id = f.friends_accepter)
where f.friends_status = 1
and i.user_id != $current_user_id
You did not give a structure for the items table so this is a guess
SELECT * FROM item i
LEFT JOIN friends f ON f.friends_status = 1 AND f.friends_inviter = i.userid
WHERE i.status = 1 OR f.friends_status IS NOT NULL`

php MySql QUERY for Friends relations Table help

EDIT by:lawrence.
I got the right query now
select *
from users, friends
where (users.id=friends.user_id1 and friends.user_id2=$profileID) or (users.id=friends.user_id2 and friends.user_id1=$profileID)
Question answered
I need some help joining results from my friends and users table
This is what my friends table look like
id user_id1 user_id2
1   | 2         | 3
1   | 2         | 4
1   | 2         | 5
1   | 6         | 2
Users table
id name
2 |  sarah
3 |  emma
4 |  lawrence
5 |  cynthia
6 |  suzie
I could easily just have two rows for each relation and do a simple query.
But i prefer having one row per relation,
So lets assume that we are watching page member.php?profile=2
and there is a list of friends, what does the query look like.
This works fine if i have two rows per relation but i dont want that....
SELECT * FROM friends, users WHERE friends.user_id1 = $profileID AND friends.user_id2 = users.id ORDER BY friends.id DESC LIMIT 16
Do you get me? something along like
SELECT * FROM friends,users WHERE friends.user_id1 = $profileID AND ALSO WHERE friends.user_id2 = $profileID AND THEN GET FROM users WHERE users.id = friends.user_id1 AND ALSO WHERE users.id = friends.user_id2
I hope I made myself clear
I'm not sure i understand your question but won't this do?
SELECT * FROM friends, users where friends.user_id1 = $profileID or friends.userid2 = $profileID and users.id = friends.user_id1 or users.id = friends.user_id2
You want a left join (using the LEFT JOIN operator), not a cartesian join (using the FROM table1, table2 syntax).
http://www.w3schools.com/sql/sql_join_left.asp
Tip: With your cross-reference table instead of having an id column you can create a compound key.

Categories