I have a query that retrieves the users that are online, and a users friends. Now I want to know the best way to combine the two so I can get the results of the users friends that are online.
Friends query:
SELECT
CASE WHEN userID=$session
THEN userID2
ELSE userID
END AS friendID
FROM friends
WHERE userID=$id OR userID2=$session
LIMIT 18
users online:
SELECT *
FROM usersActivity
WHERE setActivity!=3
AND userID!=$session
usersActivity.userID needs to match friendID
Query should be:
SELECT users.name
FROM usersActivity
INNER JOIN friends ON
(usersActivity.userID = usersActivity.userID AND usersActivity.userID2 = $session) OR
(usersActivity.userID2 = usersActivity.userID AND usersActivity.userID = $session)
INNER JOIN users ON
(usersActivity.userID = users.userID) OR
(usersActivity.userID2 = users.userID)
WHERE usersActivity.setActivity!=3
AND usersActivity.userID!=$session
AND users.userID != $session
GROUP BY users.id
You may use COUNT(user.id) if you want only count of users. Or select all names (store them for later use in listing) and use only mysql_num_rows() for getting actual number of friends online
I think I understand what your after:
SELECT userID FROM usersActivity
WHERE setActivity !=3
AND userID IN(
(SELECT userID FROM friends WHERE userID2=$id)
);
This assumes you have double rows for your friend linking table and $id is the current logged in user.
userID userID2
1 2
2 1
Using subqueries in your where statement should consolidate this. Not sure if this will be faster or not, depends on how you are doing things so profile it. You can join on your users table to get the friends name information and what other info you need.
Related
I have tables:
likes - id, user_id, like_user_id<br>
users - id, name, email ...,<br>
friends - id, user_id, friend_id, status<br>
Is it possible to sort it with one SQL query first to show the friends then the other users.
Any help would be appreciated.
Thank you.
I tried this and it works, but the problem is it give me double results of users:
select *
from `likes`
left join `users` on `users.id` = `likes.user_id`
left join `friends` on `friends.user_id` = `likes.user_id`
or `friends.friend_id` = `likes.user_id`
where `likes.id` = 1
order by `friends.user_id` = 5
or `friends.friend_id` = 5
You need to work with a UNION here to merge the liked users with the befriended users. Upon doing this, you can create an artificial column friend, that you fill with 1 in the friend query and 0 in the like query. Later on you can order by that column.
SELECT
friends.user_id,
1 as friend,
users.*
FROM
friends
JOIN users ON users.id = friends.friend_user_id
UNION SELECT
likes.user_id,
0 as friend,
users_liked.*
FROM
likes
JOIN users as users_liked ON likes.like_user_id = users_liked.id
WHERE
user_id = '$userId'
ORDER BY friend DESC, id ASC
This will return a list of all friends, followed by a list of all liked users.
I have two tables: publick_feed and users
I want to SELECT all from public_feed and also SELECT a three columns from users whose id is the same of user_id in public_feed
and assign the rows returned from public_feed to the column in users table ( correspondent)
I try this:
<?php
$sql = "
SELECT * FROM public_feed
WHERE user_id IN
(SELECT id FROM users) AND
(SELECT Firstname,Lastname,Avatar FROM users WHERE id IN(SELECT user_id FROM public_feed))
";
$query = mysqli_query($dbc_conn,$sql);
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
//echo rows with correspondent details from the users table
echo $row['user_id'];
}
}
<?
Please any help will be much appreciated.
Thank you.
Or version with left join in case if there is no user in public_feed, and you still want to fetch user data
SELECT
u.*, f.*
FROM
public_feed f LEFT JOIN
users u ON f.user_id = u.id;
Because author asked for explanation, here it is:
First we are going to use table name alias to make query shorter
public_feed f
and
users u
we are saying that want to refer to tables with an alias. Of course * means that we want to select all columns
SELECT users.*, public_feed.*
is equal to
SELECT u.*, f.*
Of course you can use any other letters as an alias
Next we are saying that public_feed.user_id must be equal to users.id. But when public feed entry does not exists just display columns with null values. This is why we are using LEFT JOIN instead of INNER JOIN. In general JOINS are used to fetch related data from more than one related tables.
ON keyword is saying values from which columns in the tables must be equal to satisfy the request
I think doing a join would be cleaner than using a complicated subquery:
SELECT u.Firstname,
u.Lastname,
u.Avatar,
COALESCE(pf.User_id, 'NA'),
COALESCE(pf.Post, 'NA'),
COALESCE(pf.Date, 'NA')
FROM users u
LEFT JOIN public_feed pf
ON u.Id = pf.User_id
I chose a LEFT JOIN of users against public_feed on the assumption that every feed will have an entry in the users table, but not necessarily vice-versa. For those users who have no feed entries, NA would appear in those columns and that user would appear in only a single record.
I'm sorry this has probably been answered hundreds of time but I'm totally lost between different scenarios here.
What I want is pretty simple. I have 2 tables "bets" and "users".
In the table "bets", I put the UserID instead of the UserName. In the table "users", the UserName is linked to the UserID.
I would like to be able to read the data from the table "bets" and display the UserName instead of the UserID, so I will need some sort of code to match the UserID contained in the table "bets" and return the UserName instead.
The MySQL query I have for now:
$sql5="SELECT * FROM Bets, Users WHERE GameID = '$NGnumber' ORDER BY DrawOrder";
$result5 = mysql_query($sql5) or die(mysql_error());
while($rows5 = mysql_fetch_assoc($result5)){
...
I can easily echo $rows5['UserID'] but I would like the UserName (in the Users table) instead. How can I do that?
Thanks!
Use inner join:
SELECT * FROM Bets INNER JOIN Users ON Bets.userID = Users.userID WHERE GameID = '$NGnumber' ORDER BY DrawOrder
Replace the query:
SELECT * FROM Bets b INNER JOIN Users u
ON b.GameID = u.GameID
WHERE GameID ='$NGnumber' ORDER BY DrawOrder"
I'd like to firstly point that I'm not very good at advanced MySQL just yet. So please forgive me. What I am trying to do is create a friends list like what's in the image below:
Here is my db structure:
friends table:
users table:
Here is my code so far:
<?php $query3 = $this->db->query("SELECT * FROM friends WHERE node1id = '{$myuserid}'");
foreach($query3->result() as $row1) {
echo $row1->node1id."<br>"; } ?>
I know this code isn't logically correct. What I am trying to do is pull in the users table. And if relationType = friends, display firstname and lastname of the user in the friends list. I have two variables. $selectedId and $myuserid. $selectedId is the id of the profile the user is viewing. and $myuserid is the id of the logged in user. How would I code this type of feature logically?
SELECT username FROM users
WHERE userid IN
(SELECT node2id FROM friends WHERE node1id = '{$myuserid}'
AND relationType = 'friends')
and
echo $row1->username
For mutual friends you could do this
EDIT: Just realised last version of this wasn't right, fixed now (untested)
SELECT username FROM users
WHERE userid IN
(SELECT node2id FROM (
(SELECT node2id FROM friends WHERE relationType = 'friends' AND node1id <> '{$myuserid}' AND node1id IN
(SELECT node2id FROM friends WHERE relationType = 'friends' AND node1id = '{$myuserid}')))
WHERE node2id IN (SELECT node2id FROM friends WHERE relationType = 'friends' AND node1id = '{$myuserid}'))
This first selects friends, then it selects the friends of those friends which is not equal (not equal is <>) to yourself. It then only selects from that list the friendIDs which match your your own friend IDs. It then selects the name of these users from the users table.
You can do a select inside of a select like below:
SELECT * FROM users WHERE idusers IN (
SELECT node2id FROM friends WHERE node1id = $myUserId
)
Here's how to get all friends of a particular user ($selectedid), and determine whether or not each of their friend is a mutual friend:
SELECT b.*,
c.myfrnd IS NOT NULL AS isMutual
FROM (
SELECT IF(node2id = '$selectedid', node1id, node2id) AS usrfrnd
FROM friends
WHERE '$selectedid' IN (node1id,node2id) AND
relationType = 'friends'
) a
JOIN users b ON a.usrfrnd = b.userid
LEFT JOIN (
SELECT IF(node2id = '$myuserid', node1id, node2id) AS myfrnd
FROM friends
WHERE '$myuserid' IN (node1id,node2id) AND
relationType = 'friends'
) c ON b.userid = c.myfrnd
ORDER BY isMutual DESC
The column isMutual will contain 1 if the friend is a mutual friend, otherwise 0 if not. Mutual friends show up first in the result set.
The thing you have to consider is that a user could be in either columns node1id or node2id, so in order to get a consistent join, we use a subselect to force the friends of the parameter userids ($selectedid and $myuserid) to be in the same column.
Let me know how this works.
Update: I figured it out. See my answer below.
I'm trying to write some logic at the application level to identify the friends (mutual followers)in the table below. My query has returned the data in a format similar to the table below (borrowed from this question, but I don't need a query, that part's done):
A B
1 2 // mutual followers, so "friends"
2 1 // mutual followers, so "friends"
1 3 // user 1 is following 3
1 4 // user 1 is following 4
So how can I write some logic which shows the users where A = B and B = A, but in different rows? Using PHP/codeigniter.
In response to a request, here's the SQL tables and query:
Users table - uid, fname, lname
Followers table - user_id, follow_id
Select users.uid, users.fname, users.lname, u.uid, u.fname, u.lname
FROM users
INNER JOIN follows f on (f.user_id=users.uid)
INNER JOIN users u on (u.uid=f.follow_id)
I think you want something like this:
$results = array(array(1,2),array(2,1),array(1,3),array(1,4));
$mutual_users = array_filter($results,function($elem)use($results){
if(in_array(array_reverse($elem),$results)){
return true;
}
});
print_r($mutual_users);
Okay, I figured it out. I needed a second INNER JOIN for the followers table. I added the code below to my SQL query, and it worked.
INNER JOIN followers f2 ON u.id = f2.user_id AND users.id = f2.follow_id