I am trying to build an ajax chat system. Basically I have 2 tables, the users table and the pm (private messaging) table. I am joining these tables.
How can I get all the information from the users table for person 1, and person 2 (receiver and sender) in one query so I can order all the chats by the correct time?
I tried using the normal join to get this done, but I have realised that it sends only one set of data from the users table. Is it possible to join the same table twice?
I have tried this:
SELECT pm.id, pm.message, pm.reciever, pm.sender, pm.senttime, pm.rread,
u.username, u.name, u.surname, u.fullname, u.profile, u2.username, u2.name,
u2.surname, u2.fullname, u2.profile
FROM pm, users u, users u2
WHERE (pm.reciever = 1 AND pm.sender = 2) OR (pm.reciever = 2 AND pm.sender = 1)
But it is returning multiples.
You have to compare your ids from the different tables:
SELECT pm.id, pm.message, pm.reciever, pm.sender, pm.senttime, pm.rread, s.username, s.name, s.surname, s.fullname, s.profile, r.username, r.name, r.surname, r.fullname, r.profile
FROM pm, users s, users r
WHERE (r.id = pm.reciever) AND (s.id = pm.sender) AND ((r.id = 1 AND s.id = 2) OR (r.id = 2 AND s.id = 1))
Related
I'm having a hard time wrapping my head around the SQL I need to pull data about other users that belong to the same group as the logged in user in my PHP application.
The data structure looks like this:
User Table
user_id
name
status
bio
Group Table
group_name
user_id
What I'm trying to do is create a page that shows the bios for all of the other members of the same group or groups that a user belongs to.
I've tried this SQL:
SELECT list.listname, list.user_id, list.groupname
FROM list
LEFT JOIN user_group ON list.user_id = user_group.user_id
WHERE user_group.user_id = 'test#testuser.com'
ORDER BY list.groupname
But I just get back the bio for test#testuser.com, and no other bios. If I remove the WHERE portion of the statement, I get all bios for all users, and not just the bios of users that are in the same group as my test#testuser.com. The logged in user may belong to more than one group.
Any ideas about how to grab this data?
This returns the groups for a given user:
SELECT l.groupname
FROM list l
WHERE l.user_id = 'test#testuser.com'
ORDER BY l.groupname;
If you want all users in the groups
SELECT l.listname, l.user_id, l.groupname
FROM list l LEFT JOIN
user_group ug
ON l.user_id = ug.user_id
WHERE l.groupname IN (SELECT l2.groupname
FROM list l2
WHERE l2.user_id = 'test#testuser.com'
)
ORDER BY l.groupname;
You can do it by self-joining the list table:
SELECT l.listname, l.user_id, l.groupname
FROM list l
LEFT JOIN user_group ug ON l.user_id = ug.user_id
INNER JOIN list l2 ON l2.groupname = l.groupname
AND l2.user_id = 'test#testuser.com'
ORDER BY l.groupname;
I have a query that looks up people's full names based on their record ID's in a table called users. The full names are tied to their roles in another table (table1). This requires multiple joins to the users table:
SELECT table1.id, users.full_name AS "Requester",
users.full_name AS "Approver,"
users.full_name AS "Ordered By",
users.full_name AS "Received By"
FROM table1
JOIN users AS users
ON table1.requester_id = users.id
JOIN users AS users2
ON table1.approver_id = users2.id
JOIN users AS users3
ON table1.ordered_by = users3.id
JOIN users AS users4
ON table1.received_by = users4.id
WHERE table1.deleted_record !=1;
The problem I'm having is with ordered_by and received_by. Often, they don't yet exist, because the order has neither been ordered nor received, so the ID for each can be 0, which has no corresponding value in the userstable. When I run this query, I should get back all 475 records that exist, but I only get back 365, because of those 0 values. How can I modify this query to make sure all rows are returned, even if ordered_by and/or received_by = 0?
First, your primary table driving the query should be table1. Then, you are using JOIN instead of LEFT JOIN. LEFT JOIN will give you a null result if no link, but not fail. In which case, you might have to use an IF for your fields value
SELECT table1.id, req.full_name AS "Requester",
app.full_name AS "Approver",
ordr.full_name AS "Ordered By",
rec.full_name AS "Received By"
FROM table1
LEFT JOIN users AS req
ON table1.requester_id = req.id
LEFT JOIN users AS app
ON table1.approver_id = app.id
LEFT JOIN users AS ordr
ON table1.ordered_by = ordr.id
LEFT JOIN users AS rec
ON table1.received_by = rec.id
WHERE table1.deleted_record !=1;
This should do it
You are looking for left join:
SELECT t1.id, ur.full_name AS "Requester",
ua.full_name AS "Approver,"
uo.full_name AS "Ordered By",
urv.uo AS "Received By"
FROM table1 t1 LEFT JOIN
users ur
ON t1.requester_id = ur.id LEFT JOIN
users ua
ON t1.approver_id = ua.id LEFT JOIN
users uo
ON t1.ordered_by = uo.id LEFT JOIN
users urv
ON t1.received_by = urv.id
WHERE t1.deleted_record <> 1;
Note that I changed the aliases on the users references from fairly meaningless u1, u2, etc. to ua, uo, and so on. Also, these need to be used in the SELECT to get the right full name.
I am working on social networking site.
I've three tables one is user table which is used to store user details, another table is follow table which is used for followers following list.
In this table I am storing user_id and follower_id.
Third table is user_friends in this I'm storing user_id and friend_userid.
I want to search the user from my friends list and follow list. For this i've written query like this:-
select f.follower_id,uf.friend_userid,u.user_id,u.first_name,u.last_name from tbl_user u
LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id
LEFT JOIN tbl_follow f ON f.follower_id = u.user_id
where uf.friend_userid != '11'
AND u.first_name LIKE '%a%'
This query returning users only who are friends it is not returning the follow users.
Any help will be appreciated. Thanks in Advance.
You're joining tbl_follow on the Follower ID being equal to the User ID. I suspect that's probably not right.
If you don't already have one you'll need a user id key in the follower table to join on, then you can change your join to;
LEFT JOIN tbl_follow f ON f.userid = u.user_id
i've done this by using following query:-
select u.user_id,u.first_name,u.last_name from tbl_user u LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id LEFT JOIN tbl_follow f1 ON f1.follower_id = u.user_id LEFT JOIN tbl_follow f2 ON f2.user_id = u.user_id where (uf.user_id = '11' OR f1.user_id = '11' OR f2.follower_id = '11') AND (u.first_name LIKE '%s%' OR u.last_name LIKE '%s%') AND u.status = '0' group by u.first_name
This query returning me all the users who are my followers, friends and to whom i am following.
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
I am making a cookie based favorite system and need to join data from two tables based on the unique user id stored in the cookie so I can tell what items that use has marked as favorites.
I know I need to do a JOIN but have not used them much and dont really have my head around them yet.
Existing query that selects the items from the db:
$query = mysql_query("SELECT *, UNIX_TIMESTAMP(`date`) AS `date` FROM songs WHERE date >= DATE_SUB( NOW( ) , INTERVAL 2 WEEK ) ORDER BY date DESC");
My favorites table is setup as: ID FAVORITE USERID where ID is the primary key, FAVORITE is the song ID from table songs and USERID is a hash stored in a cookie.
I need to join in all the rows from the favorites table where the USERID field matches the cookie hash variable.
I also need to gather the total number of rows in favorites that match the song id so I can display a count of the number of people who set the item as favorite so I can display how many people like it. But maybe need to do that as a separate query?
This should do it, I would imagine:
$user_id = intval($_COOKIE['user_id']);
$query = mysql_query(sprintf("
SELECT *
FROM songs s
INNER JOIN favorites f
ON f.favorite = s.id
WHERE f.userid = %s
", $user_id));
You should probably read up on the different types of joins.
And then to get the total amount of rows returned, you can just call mysql_num_rows on the result:
$favorite_song_count = mysql_num_rows($query);
EDIT: To select all songs but note which are favorited, you would do this:
$query = mysql_query(sprintf("
SELECT s.*, f.id as favorite_id
FROM songs s
LEFT JOIN favorites f
ON f.favorite = s.id AND f.userid = %s
", $user_id));
By switching it from an INNER JOIN to a LEFT JOIN we are selecting all songs even if they don't have a corresponding record in the favorites table. Any songs that are favorites of the user_id provided will have a non-NULL value for favorite_id.
You can have logical (and, or, ...) operators in join conditions:
select t1.*
from t1
join t2 on t1.id = t2.fid and t2.foo = 'blah'
If you are also querying the total number of times each song has been "favorited" then you need a group by construct also, like this way:
select *, count(f.id)
from songs as s
left join favorites as f on s.id = f.favorite and f.userid = <hash>
group by s.id