Returning the most recent messages from MySQL? - php

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..

Related

how to left join the relation to join five latest rows only

i am joining the latest relation row with the following code.
SELECT pos.* FROM users AS usr LEFT JOIN posts AS pos ON pos.user_id = usr.id WHERE
pos.id = (
SELECT MAX(id)
FROM posts
WHERE user_id = usr.id
);
if I want to join the second last row only here is the code
SELECT pos.* FROM users AS usr LEFT JOIN posts AS pos ON pos.user_id = usr.id WHERE
pos.id = (
SELECT id
FROM posts
WHERE user_id = usr.id
ORDER BY id DESC LIMIT 1,1
);
The question is what i can do if I want to join the latest five rows again in each relation?

Mysql join on three tables to get list of unique data

I want to show all those users from Users table, whose id is present in table favorite_group_users as user_id for a user whose favorite_groups.id = favorite_group_users.id.
I used below query but it is returning null.
select users.id as user_id, users.first_name as name,
favorite_groups.id as group_id,
favorite_groups_users.user_id as carrier_id
from users
inner join favorite_groups
on users.id = favorite_groups.user_id
inner join favorite_groups_users
on favorite_groups.id = favorite_groups_users.favorite_group_id
where users.id = 38;
You may try nested select
select
favorite_groups.group_id, users_group.user_id
from
favorite_groups_users ,
(select
favorite_groups_users.favorite_group_id,
users.user_id
from
users, favorite_groups_users
where
users.id = 38 and
users.id = favorite_groups.user_id
) users_group
where
users_group.favorite_group_id=favorite_groups.group_id

get unique records between two fields from mysql in php

I have a table where my private message are stored which I done with my friends.
I have table structure as shown in image
Suppose my logged user_id is 1, Now I want show his last five unique conversations with last message of each conversation.
Not very elegant but working:
SELECT m1.*
FROM private_msgs m1 LEFT OUTER JOIN private_msgs m2
ON (m1.message_from_uid=m2.message_from_uid AND m1.message_to_uid=m2.message_to_uid AND m1.message_time<m2.message_time)
WHERE m2.message_id IS NULL AND m1.message_from_uid=$uid
ORDER BY message_time DESC;
Add limit to 5 or whatever you want
EDIT. Sorry I didn't notice that UID can be as sender or receiver. Can you publish table with sample data for example here: http://sqlfiddle.com?
Anyway that should to the trick:
WHERE m2.message_id IS NULL AND (m1.message_from_uid=$uid OR m1.message_to_uid=$uid)
Here it is, long and ugly. You can replace temporary tables as subqueries in one big final query. Explanations are at the end.
CREATE TEMPORARY TABLE IF NOT EXISTS t1 AS
(SELECT message_id, message_from_uid, message_to_uid, message_time
FROM private_msgs
WHERE message_from_uid=$UID)
UNION
(SELECT message_id, message_to_uid, message_from_uid, message_time
FROM private_msgs
WHERE message_to_uid=$UID);
CREATE TEMPORARY TABLE IF NOT EXISTS t2 AS SELECT * FROM t1;
SELECT m.*
FROM (t1 LEFT OUTER JOIN t2
ON (t1.message_from_uid=t2.message_from_uid AND t1.message_to_uid=t2.message_to_uid AND t1.message_time<t2.message_time))
JOIN private_msgs m ON t1.message_id=m.message_id
WHERE t2.message_id IS NULL AND t1.message_from_uid=$UID
ORDER BY t1.message_time DESC;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
t1 temporary table takes all messages where $UID is a sender and union them with messages where $UID is receiver, but puts $UID as sender. In t1 doesn't matter who is sender/receiver. What does matter that these are conversations between $UID and someone else.
t2 is copy of t1, because in MySQL you can't join temporary table with itself.
And finally we do the query. We join t1 and t2, take only newest messages in every conversation and sort it from latest to oldest. As in t1 and t2 sender and receiver are mixed we do the last join with private_msg to get original data.
PS. Sorry for my english, I'm not native speaker.
Found among my old code:
select m.*
from private_messages m
join user_table s ON m.sender_id = s.id
join user_table r ON m.receiver_id = r.id
join (select if(sender_id = $UID, receiver_id, sender_id) as user_id_other,
max(posted_at) AS date_time_max from private_messages
where (sender_id = $UID OR receiver_id = $UID)
group by if(sender_id=$UID, receiver_id, sender_id)
) AS t
on if(m.sender_id = $UID, m.receiver_id, m.sender_id) = user_id_other
AND m.posted_at=date_time_max
where m.sender_id = $UID OR m.receiver_id = $UID
order by m.posted_at desc
Not responsible for result, but this can help. By itself variables must be replaced, I did not modify the code very much, as you can see. But this piece of... code... worked.
In your case smths like:
select m.*
from YOUR_MESSAGES_TABLE m
--- OPTIONAL: join YOUR_USER_TABLE s ON m.message_from_uid = s.id
--- OPTIONAL: join YOUR_USER_TABLE r ON m.message_to_uid = r.id
join (select if(message_from_uid = $YOUR_USER_ID, message_to_uid, message_from_uid) as user_id_other,
max(message_time) AS date_time_max from YOUR_MESSAGES_TABLE
where (message_from_uid = $YOUR_USER_ID OR message_to_uid = $YOUR_USER_ID)
group by if(message_from_uid=$YOUR_USER_ID, message_to_uid, message_from_uid)
) AS t
on if(m.message_from_uid = $UID, m.message_to_uid, m.message_from_uid) = user_id_other
AND m.message_time=date_time_max
where m.message_from_uid = $UID OR m.message_to_uid = $UID
order by m.message_time desc limit 5
Test: http://sqlfiddle.com/#!9/f66fd8/4

group messages by same users

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

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'

Categories