MySql combining results and applying to a second table - php

I am having difficulty getting the results from 1 query and making them display in alpha order when the results are numerical.
TABLE1: "users" ROWS: user_id, username
TABLE2: "friends" ROWS: user_id, friend_id, confirmed
When YOU friend someone or they friend you, and you confirm, you create a "confirmed state" of 1.
With that in mind:
If I make the following query:
SELECT user_id
FROM friends
WHERE friend_id = 4
AND confirmed = 1
UNION
SELECT friend_id
FROM friends
WHERE user_id = 4
AND confirmed=1
I get a list of all my friends id's. I am user '4'.
What I would like to do now is take this result and look up their usernames from "users" and put them into Alphabetical order to compile a "Friends List"
I've tried all combinations of JOIN etc, but just cant get my head round it.
Please help, Any ideas?

SELECT u.*
FROM user u
JOIN
( SELECT user_id
FROM friends
WHERE friend_id = 4
AND confirmed = 1
UNION
SELECT friend_id
FROM friends
WHERE user_id = 4
AND confirmed=1
) x
ON x.user_id = u.user_id
ORDER
BY something

Related

top first friends then the other users from like list

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.

subqueries: select from one table based on matching user ids with team ids and output 2 dimensional array

I want to select from login_users to get the following fields: name, username, and user_id.
I have a separate table teams with the team_id, as well as the associated user_id, so for example I might have bob with team1, jack with team2, jim with team1, and paul with team2 (all separate rows, not bob and paul -> team2).
If I provide a function with the team_ id I want to be able to find all the associated user_ids, and then match that data with login_users to output a two dimensional array that has name, username, and user_id of all the team members.
SELECT username, user_id, name FROM login_users WHERE EXISTS ( SELECT user_id FROM teams WHERE team_id= $team_id );
I know it has something to do with sub queries I just have never done them before, and I feel that I am on the wrong track. Furthermore, how would I then go about producing a two dimensional array?
Why only subquery ?? why not JOIN
SELECT u.username, u.user_id, u.`name` FROM login_users u
JOIN teams t ON(u.user_id = t.user_id)
WHERE team_id= $team_id
If you want to do this with an "exists" subquery, then it needs to be a correlated subquery:
SELECT username, user_id, name
FROM login_users
WHERE EXISTS (SELECT user_id
FROM teams
WHERE team_id = $team_id and
teams.user_id = login_users.team_id
);
You are missing the condition on the user_id. That version of the query is saying "get me all rows from login_users when team_id exists in teams".

Programming a friends list feature

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.

MYSQL combine two queries to get the functionality

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.

MySQL query with 2 tables join

I have a users like this:
id username
1 user1
2 user2
3 user3
and a msgs like this:
t_id sent_by id msg
1 2 1 whatever
2 3 1 is
3 2 1 here
Where users.id is a primary key and msgs.id is a foreign key. In the msgs table, id is the destination of the message sent by sent_by.
I want to select and display the username of sent_by as long as the logged in user (via sessions) is the msgs.id.
To clarify things, here is the pseudocode of what I wanted to do:
Users has logged in. Store its userid to session.
Display the distinct usernames of who sent me (the logged in user) the messages. In the example above, the display will be: user2, user3 if I have a user id of 1.
I was thinking of using join but ended up doing 2 queries for the sent_by and ids. It seems not an efficient query.
What should I do?
This is a straightforward JOIN since you only wish to return usernames of the sent_by ids.
$sql = "SELECT DISTINCT
users.username
msgs.sent_by
FROM users JOIN msgs ON users.id = msgs.sent_by
WHERE id = {$_SESSION['my_userid']}";
SELECT DISTINCT u.username, m.sent_by
FROM msgs m
INNER JOIN users u ON u.id = m.sent_by
WHERE m.id = {$_SESSION['userid']}
ORDER BY m.t_id DESC

Categories