group messages by same users - php

I have 2 tables .. 1- users,,2-messages
I wrote this query but it doesn't show the last subject and I need last subject
select (
CASE WHEN messages.sender = 68314 THEN messages.receiver ELSE messages.sender END
) AS user_id,
MAX(messages.added) last_added,messages.subject,
MAX(messages.id) as last_id,users.username
FROM messages
INNER JOIN users ON users.id = IF(messages.sender = 68314, messages.receiver, messages.sender)
WHERE (messages.sender = 68314 or messages.receiver = 68314) AND messages.sender!=0
GROUP BY
(
CASE WHEN messages.sender = 68314 THEN messages.receiver ELSE messages.sender END
)
ORDER BY last_added DESC
It shows first subject, not the last one.

please give this query a try. It first select max(id) of messages of people talking to id 68314 assuming those are created last...and joins back with messages, and the joined with users to get the other person's name.
SELECT last_messages.user_id,
m.added as last_added,
m.subject,
last_messages.last_id,
u.username
FROM messages m
INNER JOIN
(SELECT IF(sender = 68314,receiver,sender) as user_id,
MAX(id) as last_id
FROM messages
WHERE IF(sender = 68314,sender,receiver) = 68314
GROUP BY user_id
)last_messages
ON last_messages.last_id = m.id
INNER JOIN users u ON last_messages.user_id = u.id
ORDER by last_added;
sqlfiddle

Related

MySql query for selecting latest message from the conversation and messages table join

Please tell me what is wrong with this code, this returns all the conversations, but it returns latest message for only first conversation.
SELECT
conversations.*,
messages.message,
patients.first_name as fullname,
patients.city,
patients.thumb,
patients.gender,
patients.online_status
FROM
patients
INNER JOIN conversations
ON conversations.patient_id_fk = patients.id
LEFT JOIN messages
ON messages.conversation_id = conversations.id
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z
WHERE z.therapist_id_fk = conversations.therapist_id_fk
)
WHERE conversations.therapist_id_fk='1'
GROUP BY conversations.id
ORDER BY messages.message_id DESC
You want the maximum message for the conversation not the therapist, so I suspect you want this in this subquery:
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z
WHERE z.message_id = conversations.id
)
I'm not sure the outer GROUP BY is correct (it may not be needed at all and it seems to conflict with the columns of the SELECT), but without sample data and desired results, it is hard to tell.
EDIT:
I see, the problem is the filtering on therapist id in the outer query. That makes this a bit more complicated:
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z JOIN
conversations c
ON m.conversation_id = c.id
WHERE c.therapist_id_fk = 1 AND -- restriction on subquery
z.message_id = conversations.id -- correlation to outer query
)
Don't use single quotes for constants unless the column is a string or date.
SELECT
conversations.*,
messages.message,
patients.first_name as fullname,
patients.city,
patients.thumb,
patients.gender,
patients.online_status
FROM
patients
INNER JOIN conversations
ON conversations.patient_id_fk = patients.id
LEFT JOIN messages
ON messages.conversation_id = conversations.id
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z
WHERE z.conversation_id = conversations.id
)
WHERE conversations.therapist_id_fk='1'
ORDER BY messages.message_id DESC
Found the issue. It was here:
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z
WHERE z.conversation_id = conversations.id
)
I was using this:
AND messages.message_id =
(
SELECT MAX(message_id)
FROM messages z
WHERE z.therapist_id_fk = conversations.therapist_id_fk
)
I was able to solve the problem with this query
SELECT conversations.*,m.message FROM `conversations` LEFT JOIN messages as m on conversations.id = m.conversation_id AND m.id = (SELECT MAX(ms.id) from messages as ms where ms.conversation_id = conversations.id)
I left join the messages and when doing so i select the top most message. Order by can be used to give the order by date
Your problem is the bit:
SELECT MAX(message_id)
FROM messages z
WHERE z.therapist_id_fk = conversations.therapist_id_fk
This query only matches exactly one message. You'd need something a bit different.
Try this:
SELECT
conversations.*,
messages.message,
patients.first_name as fullname,
patients.city,
patients.thumb,
patients.gender,
patients.online_status
FROM
patients
INNER JOIN conversations
ON conversations.patient_id_fk = patients.id
LEFT JOIN messages
ON messages.conversation_id = conversations.id
WHERE conversations.therapist_id_fk='1'
AND messages.message_id IN ( -- new bit
SELECT MAX(message_id) FROM messages z GROUP BY z.conversation_id
)
GROUP BY conversations.id
ORDER BY messages.message_id DESC

how to get latest messages from all users

I have two tables one is for users and other is for messages i want the latest messages of every user who sent the message to user 1 my code is below
SELECT u.profile_pic
, u.username
, u.firstname
, u.lastname
, m.message_from
, m.message_body
FROM user u
JOIN messages m
ON m.message_from = u.user_no
WHERE m.message_to = $userno
ORDER
BY m.sent_time DESC
It would be easier to give you an answer if you could include your table structures (is there a unique id on the messages table?). But from the information in your question, this should work:
SELECT
u.profile_pic,
u.username,
u.firstname,
u.llastname,
m.message_from,
m2.message_body
FROM user u
JOIN (SELECT message_from,message_to,max(sent_time)
FROM messages
GROUP BY message_from,message_to) m
ON user.user_no = messages.message_from
AND messages.message_to = '$userno'
JOIN messages m2 ON m.message_from = m2.message_from
AND m.message_to = m2.message_to
AND m.sent_time = m2.sent_time
Basically, the subselect will pull out all of the latest messages from one user to another, which you then join against to filter out all the others.
Use LEFT JOIN to message table on same user and newer sent_time. The latest of each user is the one that doesn't have such message:
SELECT profile_pic,username,firstname,lastname,messages.message_from,messages.message_body
FROM user
JOIN messages ON user.user_no = messages.message_from
LEFT JOIN messages AS newermessages ON user.user_no = newermessages.message_from AND messages.sent_time < newermessages.sent_time
WHERE messages.message_to = '$userno'
AND newermessages.id IS NULL
ORDER BY messages.sent_time DESC
The latest message from each user:
SELECT a.*
FROM messages a
JOIN
( SELECT message_from
, MAX(sent_time) max_sent_time
FROM messages
GROUP
BY message_from
) b
ON b.message_from = a.message_from
AND b.max_sent_time = a.sent_time;
The remainder of this problem has been left as an exercise for the reader.
Try adding the field of the ORDER BY clause into your selection:
SELECT u.profile_pic
, u.username
, u.firstname
, u.lastname
, m.message_from
, m.message_body
, m.sent_time
FROM user u
JOIN messages m
ON m.message_from = u.user_no
WHERE m.message_to = $userno
ORDER
BY m.sent_time DESC

getting data from four tables with tight WHERE clause

i need help getting data from different tables and insert into other different table Here are the Queries
"SELECT commentID, date, comment, subject, parentID, aBUserID FROM comments WHERE status = 'APPROVED'"
"SELECT topicID, subForumID, aBUserID, lastPostID, views, replies, startDate FROM topic WHERE status = 'APPROVED' AND topicID = $parentid";
// $parentID need to be matched from above query parentID,
"SELECT userName FROM users WHERE aBUserID = $cmtaBUserID";
// $cmtaBUserID = aBUserID from first query
"SELECT userName FROM users WHERE aBUserID = $topicaBUserID";
//$topicaBUserID = aBUserID from second query
Last 2 queries are from same table but using different where clause
i used different inner join left join from solutions posted here but non of these worked for me stuck since last 2 weeks please help
PS data from all above Queries will be inserted to a single table i need these to be combined so i can have them all in one place
If you want to perform the operation in same query use 'OR'
"SELECT userName FROM users WHERE aBUserID = $cmtaBUserID OR aBUserID = $topicaBUserID";
Please try this
SELECT userName from users where aBUserID IN(SELECT aBUserID FROM comments WHERE status = 'APPROVED')
Couldn't test it but Maybe this is what you are looking for.
SELECT c.commentID, c.date, c.comment, c.subject, c.parentID, c.aBUserID,
t.topicID, t.subForumID, t.aBUserID, t.lastPostID, t.views, t.replies, t.startDate,
u.userName
FROM
comments c
left outer join topic t on t.topicID = c.parentID
left outer join users u on u.aBUserID = c.aBUserID and u.aBUserID = t.aBUserID
WHERE
c.status = 'APPROVED' and t.status = 'APPROVED';
try this:
SELECT
comment.[commentID],
comment.[date],
comment.[comment],
comment.[subject],
comment.[parentID],
comment.[aBUserID],
commentuser.[userName],
topic.[topicID],
topic.[subForumID],
topic.[aBUserID],
topic.[lastPostID],
topic.[views],
topic.[replies],
topic.[startDate],
topic.[userName]
FROM comments comment
LEFT OUTER JOIN users commentuser
ON commentuser.aBUserID = comment.[aBUserID]
LEFT OUTER JOIN
(
SELECT
t.[topicID],
t.[subForumID],
t.[aBUserID],
t.[lastPostID],
t.[views],
t.[replies],
t.[startDate],
u2.[userName] --user from users table joined to topics table
FROM topic t
LEFT OUTER JOIN users u
ON u.aBUserID = t.[aBUserID]
WHERE t.[status] = 'APPROVED'
) topic
ON topic.topicID = comment.parentID
WHERE comment.[status] = 'APPROVED'

MySQL count should return 0, returns nothing

I have this MySQL query, seems pretty easy:
SELECT users.nick, users.id, COUNT(pm.id) AS pms
FROM users LEFT JOIN pm ON users.id = pm.touser
WHERE users.id = :id AND pm.read = 0
GROUP BY users.id
What I want to do here is simply count all the PMs that aren't read (doesn't have "1" in "read" col). If there are any, query works fine, but when there isn't any row meeting that condition, it returns nothing.
I spent the last hour looking for solution, but it seems really odd, that it works this way. It should only print "0" while echoing "pms".
Simply:
SELECT users.nick, users.id, COUNT(pm.id) AS pms
FROM users LEFT JOIN pm ON (users.id = pm.touser AND pm.read = 0)
WHERE users.id = :id
GROUP BY users.id;
Try this
SELECT nick,id, COUNT(id) AS pms
FROM users LEFT JOIN (Select touser as id from pm where read =0) as pms1
WHERE id = :id GROUP BY id
Try reversing the table order:
SELECT users.nick, users.id, COUNT(pm.id) AS pms
FROM pm
LEFT JOIN users
ON users.id = pm.touser
WHERE users.id = :id AND pm.read = 0
GROUP BY users.id
SELECT users.nick, users.id, COUNT(pm.id) AS pms
FROM users
LEFT JOIN
pm
ON (pm.touser, pm.read) = (users.id, 0)
WHERE users.id = :id
GROUP BY
users.id
pm.read = 0 should go to the ON clause.
WHERE clause filters out all NULL values resulting from the pm miss.

Returning the most recent messages from MySQL?

I need to add a join to the following query that will join the messages_message table to the messages_threads table and return the 'body' and 'time' fields from the most recent row in messages_messages where messages_message.threadid = messages_threads.id.
Sorry that's so confusing, I don't know how else to phrase it! Here's my current query - which pulls everything correctly except the 'body' and 'time' fields.
SELECT
messages_threads.id AS threadid, messages_threads.name AS recipientsname,
senderid, username AS sendername, pictures.url AS senderpicture
FROM
messages_recipients
JOIN messages_threads
ON messages_threads.id = messages_recipients.threadid
JOIN users
ON users.id = messages_threads.senderid
JOIN pictures
ON messages_threads.senderid = pictures.userid
AND pictures.profile = 1
WHERE messages_recipients.userid = $userid
You could add a subquery of the messages_message table which would return 1 row for every thread. For example:
SELECT
messages_threads.id AS threadid, messages_threads.name AS recipientsname,
senderid, username AS sendername, pictures.url AS senderpicture
FROM
messages_recipients
JOIN messages_threads ON messages_threads.id = messages_recipients.threadid
JOIN users ON users.id = messages_threads.senderid
JOIN pictures ON messages_threads.senderid = pictures.userid AND pictures.profile = 1
JOIN ( SELECT threadid, MAX(id) AS postid FROM messages_message GROUP BY threadid ) t ON message_threads.id = t.threadid
JOIN messages_message ON t.threadid = messages_message.threadid AND t.postid = messages_message.id
WHERE messages_recipients.userid = $userid
I think you will need Group by body and time also...
or can u more specify your query..

Categories