I am creating message conversation script in PHP mysqli. I have two table inbox and sent box, this two table same columns I want to join this two table.and i want to get last message between two users.
inbox table
id from_id to_id msg sent_date
1 2 3 hi how are you? 2019-12-05 04:14:20
2 3 2 fine 2019-12-05 05:15:58
3 2 3 hi 2019-12-05 03:20:34
4 5 2 hi 2019-12-05 08:30:40
sentbox table
id from_id to_id msg sent_date
1 2 3 hi how are you? 2019-12-05 04:14:20
2 3 2 fine 2019-12-05 05:15:58
3 2 3 hi 2019-12-05 03:20:34
4 5 2 hi 2019-12-05 08:30:40
Here is my source code
<?php
if (isset($_SESSION['userid'])) {
$session_id = $_SESSION['userid'];
}
$sql = "SELECT *,
(SELECT username FROM users WHERE userid=from_id) AS from_username,
(SELECT username FROM users WHERE userid=to_id) AS to_username,
(SELECT username FROM users WHERE userid=?) AS my_username,
(SELECT profile_pic FROM users WHERE userid=from_id) AS from_profile_pic,
(SELECT profile_pic FROM users WHERE userid=to_id) AS to_profile_pic,
(SELECT profile_pic FROM users WHERE userid=?) AS my_profile_pic
FROM inbox WHERE from_id = ? OR to_id = ? ORDER BY id DESC";
if ($stmt = $con->prepare($sql)) {
$stmt->bind_param('iiii', $session_id, $session_id, $session_id, $session_id);
$stmt->execute();
}
What about this?
SELECT * from inbox i
inner join sentbox s on i.from_id = s.to_id
inner join users u on u.user_id = i.from_id
where i.from_id = 'your desired id here'
order by i.sent_date DESC limit 1;
I believe this would give you the latest communication between 2 users.
Having said that, it feels like it would be better to go with a simpler design where every communication is a transaction and you store it in a single table, with FROM and TO fields and the time of the communication. No need to do a JOIN between 2 tables here. You're duplicating data here.
Related
I have two tables
tbl_user:
id fisrtname lastname
5 John Doe
6 Peter Parker
7 Will Smith
tbl_experience:
exp_id usr_id user_reporting_to
1 5 dev#abc.com
2 6 admin#abc.com
3 7 dev#abc.com
I want to fetch those record who have same reporting email address with where condition usr_id=5 because when i am login in to my page it creates the session of user id for e.g it is now 5 in where condition using join or alias
SELECT texperience.tbl_experience_report_to_email AS tbl_experience_report_to_email,
tuser.tbl_user_fname AS tbl_user_fname,
texperience.tbl_experience_designation AS tbl_experience_designation
FROM tbl_experience AS texperience,
tbl_user AS tuser
WHERE tuser.tbl_user_fname = tuser.tbl_experience_id
AND texperience.tbl_experience_report_to_email = texperience.tbl_experience_id
AND texperience.tbl_experience_user_id = 1
SELECT tbl_user.*, tbl_experience.user_reporting_to FROM tbl_user
LEFT JOIN tbl_experience ON (tbl_user.id=tbl_experience.usr_id)
LEFT JOIN (SELECT count(*) as total_user, user_reporting_to FROM tbl_experience GROUP BY user_reporting_to) as email_group ON
(email_group.user_reporting_to = tbl_experience.user_reporting_to) WHERE email_group.total_user > 1
Basically have a subquery that group all the email address and the joined table will return those users that have emails appearing more than once in the tbl_experience.
I have chat database contains from three table (users,message,message_recipient)
and their relations here :
Database Design
the content of table is :
tabel users:
us_id username password
1 user1 pass1
2 user2 pass2
3 user3 pass3
table mesasage
id msg_body create_date creator_id
1 "Hi user2" --------- 1
2 "Hi user3 --------- 1
table message_recipient
id repient_id message_id is_read
1 2 1 0
2 3 2 0
my problem is when select the messages that user1 send to user2 the AND operator not working or there is bug with AND
the SQL Query :
SELECT message.id, message.msg_body,message.creator_id,message_recipient.recipient_id
FROM message,message_recipient
WHERE message.creator_id='1' AND message_recipient.recipient_id='2'
the output is:
id msg_body creator_id recipient_id
1 "Hi user2" 1 2
2 "Hi user3" 1 2
You need to use JOIN to do that:-
SELECT message.id, message.msg_body,message.creator_id,message_recipient.recipient_id
FROM message JOIN message_recipient ON message.id = message_recipient.message_id
WHERE message.creator_id='1' AND message_recipient.recipient_id='2'
Note:- When you are trying to get data from two or more tables then you need to use different types of Joins.
Reference:- https://www.w3schools.com/sql/sql_join.asp
You need to join them on message id. Try this:
SELECT m.id, m.msg_body, m.creator_id, mr.recipient_id
FROM message m
JOIN message_recipient mr on m.id=mr.id
WHERE m.creator_id='1' AND mr.recipient_id='2'
I added this in where clause message.id = message_recipient.message_id in your code and it's works
we can able to join multiple table using where clause .
SELECT message.id,
message.msg_body,message.creator_id,message_recipient.recipient_id FROM
message,message_recipient WHERE message.id = message_recipient.message_id and
message.creator_id='1' AND message_recipient.recipient_id='2'
I m trying to create message system where I want to list down the users with whom one has interacted with recent chat on top I know this question is duplicate as well but i cant figure out where the problem is
Here is my message table structure
user_message table
msgID sentBy sentTo message sentTime
1 3 1 Hii B 1493306882
2 3 1 Hi A 1493309615
1 1 3 Hmm 1493306882
2 1 3 Yeah 1493309615
and the query i tried is
QUERY
SELECT * FROM user_message_status LEFT JOIN users ON user_message_status.userID=users.userID
LEFT JOIN user_message ON user_message_status.msgID=user_message.msgID WHERE user_message_status.userID='".$_SESSION['userid']."'
GROUP BY user_message_status.msgID ORDER BY user_message.msgID DESC
PROBLEM:
1) When userA send msg to userB, userA name is printed in chat list instead of recipient(userB)
2) The amount of msg sent or receive equals to the number of users are listed in the chat.
user_message_status: table
msgstatusID msgID userID box read readTime
1 1 3 outbox 0 0
2 1 1 inbox 0 0
This is status table to read unread messages or delete
First update the query to the below:
SELECT *
FROM user_message_status s
LEFT JOIN users u USING userID
LEFT JOIN user_message m USING msgID
WHERE s.userID='".$_SESSION['userid']."'
GROUP BY user_message_status.msgID
ORDER BY user_message.msgID DESC
Because both tables have the same column names, to make you sql shorter and neater, you can use the USING function
Both LEFT JOIN users ON user_message_status.userID=users.userID and LEFT JOIN user_message ON user_message_status.msgID=user_message.msgID was changed. We then renamed the tables to just a single letter so you don't have to write the entire table name.
Also why your userA is sent is because, your query will return, lets say I am id '3',
msgstatusID msgID userID box read readTime
1 1 3 outbox 0 0
So from the joins, the user_message will return
msgID sentBy sentTo message sentTime
1 3 1 Hii B 1493306882
1 1 3 Hmm 1493306882
So you would have to use an if statement or turnary operation for the name and say:
if (sentBy == $_SESSION['userid'])
$name = sentTo;
else
$name = sentBy;
OR
$name = (sentBy == $_SESSION['userid']) ? sentTo : sentBy;
Basically to show the proper name of who you are talking to, you need to first check which column name to use
AS for problem 2, if you want to limit the amount then you need to add more condition. Maybe you only want outbox so you need to put AND box = 'outbox'
The below sql should help you out
SELECT
s.msgId
, m.message
, (
SELECT CONCAT(firstName, ' ', lastName)
FROM users
WHERE userId = CASE WHEN m.sentTo = s.userId
THEN m.sentBy
ELSE m.sentTo END
) AS chatWith
, m.sentTime
, s.read
FROM user_message_status s
LEFT JOIN user_message m USING (msgID)
WHERE s.userID='".$_SESSION['userid']."'
ORDER BY m.msgID DESC
Remove LEFT JOIN users u USING userID because it will be sub queried
s.msgID // used for deleteing the chat conversation
m.sentBy, m.sentTo, m.message, m.sentTime // all important data for your messages
I'm trying to get a list of suggested friends that are not within my friends but are in my friends, friends.
status of 2 being an accepted friend.
My session id is 34 and I'm friends with user 3 and user 3 is friends with user 16, so user 16 would show as a suggested friend as user 16 is not my friend.
Friends table
id | user 1_id | user2_id | status
----------------------------------
4 3 34 2
3 34 3 2
2 3 16 2
1 16 3 2
Query (What I've tried)
$user1_id=$_SESSION['id'];
$user2_id=$data['id'];
$collectmutualfriendsa = mysqli_query($mysqli,"
SELECT DISTINCT r2.user1_id
FROM
friends r
INNER JOIN friends r2
ON r.user1_id = r2.user2_id
LEFT OUTER JOIN friends r3 ON r3.user2_id = r2.user1_id AND r3.user1_id=2
WHERE r.user2_id = 2 AND r3.user1_id is null");
$user1_id = $_SESSION['id']; // 34
$user2_id = $data['id']; // 3
$query = "SELECT * FROM Friends_table WHERE user1_id = '$user2_id' AND user2_id != $user1_id;";
Okay, I tried a UNION and now have it working.
$collectmutualfriendsa = mysqli_query($mysqli,"
SELECT *
FROM friends
WHERE user2_id NOT IN
(
SELECT user1_id FROM friends WHERE user2_id = '$user1_id'
UNION
SELECT user2_id FROM friends WHERE user2_id = '$user1_id'
)
");
I need help with SQL query.
I have two tables. One is users and other one is userfriends
users table:
aid email firstname
1 example#mail.com example
2 example2#mail.com example2
3 example3#mail.com example3
4 example4#mail.com example4
userfriends tables:
reqid email friendemail status
1 example1#mail.com example2#mail.com 1 (example1 is frnds with example2)
2 example2#mail.com example4#mail.com 2 (example2 request pending)
3 example3#mail.com example1#mail.com 1 (example1 is frnds with example3)
4 example4#mail.com example1#mail.com 1 (example1 is frnds with example4)
So when status is 2 the add request is pending and at status 1 they are friends. What i want is that i want to retrieve the complete friendlist for user example1. I want to pull out names from users table for corresponding output from previous query to display as friendlist.
I think you guys are missing the fact that the searched for email could be in either column:
select u.firstname
from userfriends f, users u where
u.email='email#domain.com' and f.status=1 and
(u.email = f.email and f.friendsemail='email#domain.com')
or
(u.email = f.friendsemail and f.email='email#domain.com')
select distinct friendemail
from userfriends f
inner join users u on u.email = f.email
where f.status = 1
and u.firstname = 'example'
You need to JOIN both tables:
SELECT users.firstname
FROM userfriends UF
JOIN users U ON (U.email=UF.friendemail)
WHERE UF.email='your user'