Show Message List in SQL - php

I want to show the message list like facebook messenger where in left corner you can see all the message you make.
user_table
user_id
user_firstname
user_latsname
message_table
message_id
message_user_id
message_to_user_id
message_content
message_time_stamp
My SQL
SELECT user_table.user_id,
CONCAT(user_table.user_firstname,' ',user_table.user_lastname) AS user_fullname,
message_table.message_user_id,
message_table.message_content,
message_table.message_time_stamp
FROM user_table
INNER JOIN message_table
ON user_table.user_id = message_table.message_user_id
WHERE (message_table.message_to_user_id = '$session')
ORDER BY message_table.message_time_stamp DESC
My code works fine if someone message me first.
It show in my message list that someone message me.
But when i'm the one who make the first message.
It doesn't show in my message list.
He should reply in my message before i can see it in my message list.
But i want to show when someone message me and when i'm the one who make the first message.
message_table with sample data
user_table with sample data
result
But when i add new user in the user_table and message him. it will not show in my Message List.
I want my expected result is when i message new user it will show in my message list

your line (in sql query)
message_table.message_to_user_id = '$session'
is probably the reason, why you don't see the messages you send yourself (since you are not the recipient)
to fetch all messages you're involved in, it should probably be:
message_table.message_to_user_id = '$session' or message_table.message_user_id = '$session'
I hope $session is not user-provided, or you've got some possible sql-injection at hand ;o)

SOLUTION
SELECT user_id, user_fullname, message_content
FROM
(
(SELECT user_table.user_id,
CONCAT(user_table.user_firstname,' ',user_table.user_lastname) AS user_fullname,
message_table.message_user_id,
message_table.message_content,
message_table.message_time_stamp
FROM user_table
INNER JOIN message_table
ON user_table.user_id = message_table.message_to_user_id
WHERE (message_table.message_user_id = '$session')
)ORDER BY message_time_stamp DESC
UNION DISTINCT
(SELECT user_table.user_id,
CONCAT(user_table.user_firstname,' ',user_table.user_lastname) AS user_fullname,
message_table.message_user_id,
message_table.message_content,
message_table.message_time_stamp
FROM user_table
INNER JOIN message_table
ON user_table.user_id = message_table.message_user_id
WHERE (message_table.message_to_user_id = '$session')
)ORDER BY message_time_stamp DESC
) as id GROUP BY user_id ORDER BY message_time_stamp DESC
Here's the solution what i made in my problem. I made 2 select statement where the first select only select where i'm the one who makes the first message and the second select statements select where someone first message me. And then i Union it.

Related

I want the highest value to be on the top of the list

So I have this query and display the value, the 'time' is integer, it is often updated by clicking and when it is updated I want the highest value si on the top of the list when page is refresh, but it's not, I wonder if the grouping affects the query?
$sql= "select * FROM message
where userid_to = '$UserLoggedIn' || userid_from = '$UserLoggedIn'
group by conversation_id
ORDER BY time DESC";
I think you should be doing the aggregation on conversations inside a subquery to find the most recent time for each conversation. Then join back to your message table to obtain the full message record. I'm not sure what went wrong with your ordering, but your current query is not deterministic.
SELECT m1.*
FROM message m1
INNER JOIN
(
SELECT conversation_id, MAX(time) AS max_time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id
) m2
ON m1.conversation_id = m2.conversation_id AND
m1.time = m2.max_time
ORDER BY
m1.time DESC;
I would try doing it this way:
SELECT *, MAX(time) as time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id;

Select max value for a VARCHAR column - MySQL

My table for message inbox concept email is a primary in the table. I want to get the last message which is sent by particular email.
tbl_msg:
id
email
msg
Example Data:
Id email msg
1 xyz#gmail.com This is test
2 abc#gmail.com All is well
3 xyz#gmail.com This is test2
I want to get the last appearance of each email and msg
Id email msg
2 abc#gmail.com All is well
3 xyz#gmail.com This is test2
What I tried:
SELECT cnote.`id`,cnote.`email`,cnote.`msg` FROM `tbl_msg` cnote inner join (select distinct email,id from client_com group by email) as note
on cnote.id=note.id
Guide me if I wrong
Use This query:
SELECT m1.* FROM tbl_msgs m1 LEFT JOIN tbl_msgs m2 ON (m1.email = m2.email AND m1.id < m2.id) WHERE m2.id IS NULL;
This will join with the same table and with condition m1.id < m2.id , will get the latest one.
Another option is using subquery:
SELECT * FROM tbl_msgs WHERE id IN (SELECT MAX(id) FROM tbl_msgs GROUP BY email);
To get the latest messsage for each email address in the table you do not need a JOIN, you just need to ORDER and GROUP BY:
SELECT `id`, `email`, `msg`
FROM `tbl_msg`
GROUP BY `email`
ORDER BY `id` DESC
You can use this query:
SELECT id, email, msg FROM you_table
GROUP BY email
ORDER BY id DESC
With this one you will have only 1 row per email, and you'll have the last because is ordered by id DESC.
If you are running a PDO connection (The way I know to do it, not sure if there is a MySQLi way)
$theLastIdGiven = $handlerDbConnection->lastInsertId();
Or if you want to run it through a query, and get the last result, just add ORDER BY id DESC LIMIT 0, 1 and that will order the data by id in a descending form then get the first bit of data :)
Hope this helped you!
SELECT ID, email, Msg FROM tbl_msg WHERE ID IN (
(SELECT MAX(ID) FROM tbl_msg GROUP BY email))

distinct not working in sql query

i have two tables in my db .. one is Messages and the other is Contacts... both tables contain the mobile_number field.. in Contacts table there is no duplicate numbers ... but in Messages tables there are several duplicate numbers in mobileNo field...what i am doing is write now i am selecting the distinct mobile numbers from the Messages tables and then i am comparring the distinct numbers from the contacts table ... so if the messages_mobileNo is found on the contacts table then give me the contact name against the number otherwise messages_mobileNo ... so the problem is distinct not working .. i am not able to get the distinct numbers from the Messages table ... it is showing me the duplicate numbers
here is my query
SELECT DISTINCT Message.mobileNo,
Contact.mobileNo,
Contact.workNo,
Contact.homeNo,
Contact.other,
Contact.name,
Message.body,
Message.idTextMessage
FROM cakephp_db.textmessage AS Message
LEFT JOIN cakephp_db.contacts AS Contact ON (Message.user_id = Contact.user_id
AND ((Message.mobileNo = Contact.mobileNo)
OR (Message.mobileNo = Contact.workNo)
OR (Message.mobileNo = Contact.homeNo)
OR (Message.mobileNo = Contact.other)))
WHERE Message.User_id = 23
ORDER BY Message.idTextMessage DESC LIMIT 6
So your trying to get the last 6 messages of a person if I'm right?
SELECT Message.mobileNo,
Contact.mobileNo,
Contact.workNo,
Contact.homeNo,
Contact.other,
Contact.name,
Message.body,
Message.idTextMessage
FROM cakephp_db.textmessage AS Message
LEFT JOIN cakephp_db.contacts AS Contact ON Message.user_id = Contact.user_id
AND Message.mobileNo IN (Contact.mobileNo, Contact.workNo, Contact.homeNo, Contact.other)
WHERE Message.User_id = 23
GROUP BY Message.mobileNo
ORDER BY Message.idTextMessage DESC LIMIT 6
add a GROUP BY Message.mobileNo before your ORDER BY
If you are using MySQL SELECT DISTINCT with an ORDER BY added to it, you will have to create a temporary table where it can store its results. Here is a link offering more help:
MySQL DISTINCT Optimization

Can you use case to specify a join to use in MySQL?

I have a usermessages table in which all messages sent between two users on a site are stored.
Each message has a sourceUserId and a friendId, these are the sender and receiver.
Every user message inbox lists all sent and received messages and each message shows which user has sent or received that message.
The problem
As we are listing sending and receiving users, some columns are the wrong way around, for example if the userId of the current user is 1
sent messages will have a sourceUserId of 1
received messages will have a friendId of 1
If I try and do the whole inbox with one query then I have to currently do two joins on both sourceUserId and friendId as I can't tell which is the currently logged in user.
I already know the username of the currently logged in user so it does not seem right to have two joins when only one is needed?
I am wondering if it is possible to use some sort of case in a mysql query to effectively achieve the following and reduce the amount of data that has to be looked up each time ..
SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username
FROM usermessages um
CASE
WHEN um.friendId = 1
INNER JOIN user ON um.sourceUserId = user.id
WHEN um.sourceUserId = 1
INNER JOIN user ON um.friendId = user.id
END
WHERE (um.friendId = 1 OR um.sourceUserId = 1)
You need to use CASE for ON clause instead
SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username
FROM usermessages um
INNER JOIN user ON
CASE
WHEN um.friendId = 1 THEN um.sourceUserId
ELSE um.friendId
END = user.id
WHERE (um.friendId = 1 OR um.sourceUserId = 1)
(or move the comparison = user.id inside CASE if you like it better)
Another approach, instead of using case when, do it the boolean way:
SELECT um.message, UNIX_TIMESTAMP(um.time), um.read, user.username
FROM usermessages um
INNER JOIN user ON
(um.friendId = 1 AND um.sourceUserId = user.id)
OR
um.friendId = user.id
WHERE (um.friendId = 1 OR um.sourceUserId = 1)

unique field from mysql database to php

I have a sample database like this, in which, id is always unique, but the user_id is not unique.
id,user_id,message,msg_datetime
111,u1, msg from u1,time present here
112,u2, msg from u2,time present here
113,u3, msg from u3,time present here
114,u2, msg from u2,time present here
115,u7, msg from u7,time present here
116,u2, msg from u2,time present here
117,u1, msg from u1,time present here
118,u5, msg from u5,time present here
so i want to grab only those unique users who have messaged and order them in DESC by msg_datetime.
This is the query i have.
select id,DISTINCT user_id,msg_datetime ORDER BY msg_datetime DESC but i am getting an error as:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DISTINCT. any help here? what is the correct syntax for what i am trying to achieve?
I want to show only one entry for each user, it does not matter which ID i am showing but only 1 per user.
If you don't care which record with the same user_id query should return, then
SELECT id,user_id,msg_datetime FROM table_1 GROUP BY user_id ORDER BY msg_datetime DESC
If you want to display, for instance, the last record for each user, you need
SELECT a.user_id, a.last_time, b.id
FROM
(SELECT user_id, MAX(msg_datetime) as last_time
FROM table1)a
INNER JOIN table1 b ON (b.user_id = a.user_id AND b.msg_datetime = a.last_time)
ORDER BY a.last_time;
SELECT syntax:
SELECT (fieldlists)
FROM (table)
[WHERE (conditions)]
ORDER BY (something)
You kindof forgot to say which table you want the data from.
You misunderstand how DISTINCT works. It works on rows not fields. What you want is a groupwise maximum, also known as greatest-n-per-group.
Here's one way to do it in MySQL:
SELECT id, user_id, message, msg_datetime
FROM (
SELECT
id, user_id, message, msg_datetime,
#rn := CASE WHEN #prev_user_id = user_id
THEN #rn + 1
ELSE 1
END AS rn,
#prev_user_id := user_id
FROM (SELECT #prev_user_id := NULL) vars, Table1 T1
ORDER BY user_id, msg_datetime DESC
) T2
WHERE rn = 1
ORDER BY msg_datetime

Categories