Messaging System with PHP/MySQL - php

Hi I'm trying to make a messaging system with php and mysql.
The mysql table is simple:
id
sender
receiver
text
timestamp
I'm trying to make the messaging somewhat like Facebook/Twitter so the list is in 'conversations' and the last message in the conversation is viewed.
This is what I have atm:
(SELECT * FROM messages WHERE receiver = 13 OR sender = 13 GROUP BY receiver,sender ORDER BY id ASC) ORDER BY id ASC

SELECT messages.* FROM messages, (SELECT MAX(id) as lastid FROM messages
WHERE receiver = 13 OR sender = 13
GROUP BY CONCAT(LEAST(receiver,sender),'.',GREATEST(receiver,sender))) as conversations
WHERE id = conversations.lastid
ORDER BY timestamp DESC
what you need is a unique conversation id between the chat-partners. i've simulated this with the subquery, hope this helps

Use DESC for fetch new rows, default is ASC
(SELECT * FROM messages WHERE receiver = 13 OR sender = 13 GROUP BY receiver,sender ORDER BY id DESC)
AND SET LIMIT 1 ,1 AFTER ORDER BY
I think you need to
(receiver = '{receiver id}' AND sender = '{sender id}' ) OR (receiver ='{sender id}' AND sender = '{receiver id}' )

UPDAte:
I'm not sure if it works perfect:
SELECT * FROM messages
WHERE receiver = 13
GROUP BY receiver,sender
ORDER BY timestamp DESC
LIMIT 1
UNION ALL
SELECT * FROM messages
WHERE sender = 13
GROUP BY receiver,sender
ORDER BY timestamp DESC
LIMIT 1
to reverse the order:
ORDER BY timestamp DESC

Related

selecting last 10 distinct rows with subqueries

I want to select the last 10 rows from my messages table that have either the receiver_id = 1 or the sender_id = 1 but those which have the receiver_id = 1 have DISTICT applied on the sender_id and those which have the sender_id = 1 have the DISTINCT property applied on the receiver_id.
Basically, what am I trying to say is that I want to select the very last 10 messages either sent either received by the user with the id of 1, sent to or sent by 10 different other users.
What have i tried so far:
SELECT * FROM (SELECT DISTINCT sender_id FROM messages WHERE receiver_id = 1) ORDER BY id DESC LIMIT 10) tmp ORDER BY id ASC
SELECT * FROM (SELECT * DISTINCT receiver_id FROM messages WHERE sender_id= 1) ORDER BY id DESC LIMIT 10) tmp ORDER BY id ASC
But trying to get the separately and adding the arrays (and sorting them by the ids of the messages) didn't quite work.
So I tried making a query like so:
SELECT * FROM (SELECT DISTINCT receiver_id, sender_id FROM messages WHERE (receiver_id = 1 OR sender_id = 1)) ORDER BY id DESC LIMIT 10) tmp ORDER BY id ASC
but it turned out my query is a total mess and, of corse, doesn't return me what I wanted.
P.S.: I am using XAMPP MySQL: MariaDB
Your second paragraph is:
Basically, what am I trying to say is that I want to select the 10
very last messages (rows) stored in the database that were either sent
or received by the user with the id of 1.
This is a fairly basic query:
SELECT m.*
FROM messages m
WHERE 1 IN (m.receiver_id, m.sender_id)
ORDER BY m.id DESC
LIMIT 10;

Mysql ASC function ORDER only first ID's

I have this line:
$query = mysql_query("SELECT * FROM livechat WHERE type='public' ORDER BY id ASC LIMIT 15") ;
And this is for chat, however ASC takes only first ID comments, so it shows only 15 old comments (id1, id2 and so on). If I use DESC instead of ASC, it shows new comments, but in a bad way - newest at the top, since this is a chat, newest comments must be at the bottom.
Try creating a temporary table that contains the last 15 results, and then ordering from that table.
select * from (
select * from livechat where type='public' order by id desc limit 15
) tmp order by tmp.id asc
try like this:
$query = mysql_query("SELECT *
FROM (
SELECT *
FROM livechat
WHERE type='public'
ORDER BY id DESC LIMIT 15
) t
order by t.id") ;

display only last message from each user

Hello friends i want to display the last message from each user in this table, lets assume the $_SESSION['id'] is 1 so i want to display the last messages by each from or to user 1 here is my query:
SELECT * FROM message WHERE (msg_from='1') OR (msg_to='1') GROUP BY msg_from,msg_to ORDER BY MAX(msg_id) DESC
but when i run this it displays two messages from a user that is in the msg_from column and also in the msg_to column and it doesn't display the last inserted message, please guys, I need help.
since you are ordering by MAX(msg_id) DESC then you reqire only the first result because it will be the latest then you may do something like
SELECT TOP 1 * FROM message where msg_id IN (SELECT msg_id FROM message WHERE (msg_from='1') OR (msg_to='1') GROUP BY msg_from,msg_to ORDER BY MAX(msg_id) DESC);
or
SELECT * FROM message where msg_id IN (SELECT msg_id FROM message WHERE (msg_from='1') OR (msg_to='1') GROUP BY msg_from,msg_to ORDER BY MAX(msg_id) DESC) LIMIT 1;
hope it helps :)
Fetching the last messages for user-1 from others:
SELECT * FROM message WHERE msg_to = '1'
GROUP BY msg_from ORDER BY msg_date DESC
Fetching the last messages from user-1 to others:
SELECT * FROM message WHERE msg_from = '1'
GROUP BY msg_to ORDER BY msg_date DESC
I didn't use your MAX(msg_id) for ordering the data, instead, I used the date to get the latest messages.

How can I use order by and group by in sql?

Here is my problem:
I have these tables:
felado fogado fehide fohide datum olvasott tartalom
felado = sender, fogado = receiver,
I would like to get all where felado or fogado is me and group the lines. So If there are the next lines
sender 1 receiver 2 id 1
sender 1 receiver 2 id 2
sender 1 receiver 2 id 3
sender 2 receiver 1 id 4
I only would like to get one from these lines, the last by ID.
Now I'm trying like this:
SELECT *
FROM belso_levelezes
WHERE (felado="'.$_SESSION["userData"]["id"].'"
or fogado="'.$_SESSION["userData"]["id"].'" )
ORDER BY id DESC
GROUP BY felado, fogado
It gaves me only one from all, but not the last records. How can I get the last records from each group?
I want to get only this:
sender 2 receiver 1 id 4
You could use a subquery to create two columns that are unique per conversation. You can then group on those columns, and grab the maximum id for the conversation. The example assumes your user id is 42:
SELECT sr1
, sr2
, max(id)
FROM (
SELECT case when Sender < Receiver then Sender else Receiver end as sr1
, case when Sender > Receiver then Sender else Receiver end as sr2
, id
FROM YourTable
WHERE 42 in (Sender, Receiver)
) as SubQueryAlias
GROUP BY
sr1
, sr2
'SELECT MAX(id),felado,fegado,... FROM belso_levelezes WHERE (felado="'.$_SESSION["userData"]["id"].'" or fogado="'.$_SESSION["userData"]["id"].'" ) GROUP BY felado, fogado '

Aggregate MYSQL functions getting a value in the same row

$query = mysql_query("SELECT *, MAX(date_time) FROM messages
WHERE user_to='$current_user' OR user_from='$current_user'
GROUP BY conversation
ORDER BY date_time DESC LIMIT 0,5") or die(mysql_error());
echo $message['MAX(date_time)'];
How can I display the column 'content' that is in the same row as the date_time being selected here, so the time matches with the message? Would it be something like
echo $message['MAX(content)'];
I am trying to have 'messages' in groups (called conversations) and I want to display the most recent message. It is currently displaying the most recent time but not the most recent message.
Thanks.
If your table has an autoincrement id column to use as the message id, then the highest id value should also be the latest message in the conversation
Try Below:
SELECT * from messages as ts
LEFT JOIN (select max(id) as maxid from messages group by date_time) as tsm
ON ts.id=tsm.maxid
WHERE (ts.user_to='$current_user' OR ts.user_from='$current_user')
ORDER BY ts.date_time DESC LIMIT 0,5
Assuming id is primary key column in your message table
Order your messages by date_time and only take the first tuple (LIMIT 1).
I don't get why you aggregate if you just want the latest tuple from messages. Perhaps you can elaborate this and provide some more information about the table.
SELECT content, date_time
FROM messages
WHERE user_to='$current_user' OR user_from='$current_user'
ORDER BY date_time DESC
LIMIT 1
If you have auto incrementing key, you can try:
$query = mysql_query("SELECT * FROM messages as m
WHERE user_to='$current_user' OR user_from='$current_user' AND
id IN (SELECT MAX(id) FROM messages as m2 GROUP BY m2.conversation)
ORDER BY date_time DESC LIMIT 0,5") or die(mysql_error());

Categories