This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 1 year ago.
i have a table named messages like this :
I want query for where reciever_id equal 1 and group by sender_id and get latest record.
I USED QUERY :
SELECT `t`.* FROM(
SELECT * FROM messages
WHERE reciever_id = 1
ORDER BY created_at DESC
) `t`
GROUP BY `sender_id`
ORDER BY `id`
AND ALSO :
SELECT message, MAX(created_at)
FROM messages
WHERE reciever_id = 1
GROUP BY sender_id
ORDER BY created_at
Date's column created_at in picture exactly are the latest and id's also ordered and are latest also.
I'm done this after releasing question by below query, but i think this can cost more than others... there are another way to do this with low cost?!
Can somebody say formula how times multiple joins below query has cost?
SELECT id,sender_id,reciever_id,seen,message,created_at
FROM messages
WHERE id IN (
SELECT MAX(id)
FROM messages
WHERE reciever_id = 1
GROUP BY sender_id
ORDER BY id desc
) ORDER BY created_at DESC
Related
This question already has answers here:
Get records with max value for each group of grouped SQL results
(19 answers)
Closed last month.
i want to select row by the highest votecount from a table, but if the userid is repeted i want the just the row with the highest votecount. eg:
userId
votecount
2
2
2
12
1
20
my result is supposed to be:
1,20
2,12
this is my current code:
SELECT * from `audio` GROUP BY `userId` ORDER BY `votecount` DESC LIMIT 50
the result of my code is :
1,20
2,2
it's grouping by userId and then ordering it by votecount, which is not the desired output
select `userid`, MAX(`votecount`)
FROM `audio`
GROUP BY `userId` ORDER BY `votecount`
If that's the case and you don't have a unique row id, you need to add the other columns in the group by clause
SELECT date, promoted, status, image, name, id, userId, MAX(votecount)
FROM audio
GROUP BY date, promoted, status, image, name, id, userId
ORDER BY votecount DESC
This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Get top n records for each group of grouped results
(12 answers)
Closed 3 months ago.
I have created a table that has category id and a name and the table contains multiple matching category id so i would like to get the first data of each matching category id
based on the example table above i would like to get just the name alex and brown
Here is what i have tried
SELECT * FROM tailors
WHERE id IN(
SELECT min(id)
FROM tailors
GROUP BY cat_id,id,name,status
)
but i am getting all the record when i am just trying to get the first data of each matching category id
You just need to take out id and name from your group by clause -
SELECT * FROM tailors
WHERE id IN (SELECT min(id)
FROM tailors
GROUP BY cat_id, status
);
If the logic remains same throughout the table, and the version of the DB is 8.0+, then use such an aggregation :
SELECT name
FROM( SELECT t.*, MIN(id) OVER (PARTITION BY cat_id) AS min
FROM tailors AS t ) AS tt
WHERE id = min
assuming id is a primary key column, there will be only one minimum value per each cat_id.
GROUP BY cat_id is handled by PARTITION BY cat_id and the other columns(name and status) following it should be removed.
To return only one row use LIMIT 1:
SELECT * FROM tailors
WHERE id IN(
SELECT min(id)
FROM tailors
GROUP BY cat_id,id,name,status
) LIMIT 1
messages table
id (int)
recipient_id (int)
sender_id (int)
content (text)
created (datetime)
What I'm trying to do is get the latest message from every conversation that a user has had with other users.
Let's say i'm trying to find them for user_id = 3, this is what I have so far. It's not a great solution and feels a bit like a hack but it is working.
SELECT *
FROM messages
WHERE id IN
(SELECT MAX(id) FROM messages
WHERE `recipient_id` = 3 OR `sender_id` = 3
GROUP BY (recipient_id + sender_id))
ORDER BY created DESC
Use GROUP BY recipient_id, sender_id.
SELECT *
FROM messages
WHERE id IN
(SELECT MAX(id) FROM messages
WHERE `recipient_id` = 3 OR `sender_id` = 3
GROUP BY recipient_id, sender_id)
ORDER BY created DESC
let me clear first your question ?
you need latest message from every conversation ?
after see your query i suggest you use this
SELECT * FROM messages WHERE `recipient_id` = 3 OR `sender_id` = 3
GROUP BY (recipient_id + sender_id)) ORDER BY created DESC limit 1
it give you latest message
the reason why i give limit 1 based on your question ? Latest but if you need all from latest message till first just remove limit 1 from that query
I have a social network I am coding but it's a bit different than others, in this case there is only ever one status show per user on a feed section.
So I need to sort the status by date with the latest ones on top but also group by the userID
unfortunately I can't seem to get this working....
This is my current query:
SELECT *
FROM status
WHERE userID != "83" #This is just so my statuses don't show
GROUP BY userID
ORDER BY addedDate DESC
LIMIT 10
I expect to see the latest status results and only one per user instead I see the first statuses so the group by is working but not the order by.
Thanks in advance.
As mentioned in the comments to Robin's answer, that approach is unreliable because MySQL does not guarantee that it will always return the most recent status from each group. You must instead join your table with a subquery that selects the most recent status (based on addedDate).
SELECT *
FROM status
NATURAL JOIN (
SELECT userID, MAX(addedDate) as addedDate
FROM status
GROUP BY userID
) AS mostRecent
ORDER BY addedDate DESC
LIMIT 10
Note that if a user has multiple status updates with the same addedDate, the server will return all of them (whereas Robin's query would return an indeterminate one); if you need control over such a situation, you will need to define how one determines which such status update should be selected.
SELECT userID, max(addedDate)
FROM status
WHERE userID != "83" #This is just so my statuses don't show
GROUP BY userID
SELECT *
FROM ( SELECT *
FROM status
WHERE userID != "83"
ORDER BY addedDate DESC) AS h
GROUP BY userID
ORDER BY addedDate DESC
LIMIT 10
You must ORDER BY before GROUP BY'ing.
Example 1
Example 2
I have a database in MYSQL and it has chat table which looks like this.
I am using this query for fetching these records
SELECT * FROM (
SELECT * FROM `user_chats`
WHERE sender_id =2 OR receiver_id =2
ORDER BY id DESC
) AS tbl
GROUP BY sender_id, receiver_id
But my requirement is only 5,4 ID's records. basically my requirement id fetching last conversation in between 2 users. Here in between 2 & 3 user conversation has 2 records and we want only last one of them i.e. id = 5, here don't need id = 2.
So how we can write a query for that result?
SELECT
*
FROM
user_chats uc
WHERE
not exists (
SELECT
1
FROM
user_chats uc2
WHERE
uc2.created > uc.created AND
(
(uc.sender_id = uc2.sender_id AND uc.reciever_id = uc2.reciever_id) OR
(uc.sender_id = uc2.reciever_id AND uc.reciever_id = uc2.sender_id)
)
)
The following gets you latest record (assuming that the bigger id, the later it was created) meeting your criteria:
SELECT * FROM `user_chats`
WHERE (`sender_id` =2 AND `receiver_id` =3) OR (`sender_id` =3 AND `receiver_id` =2)
ORDER BY `id` DESC
LIMIT 1
which would be a good idea, if id is primary key and it rises along with rising value of created. Otherwise (if you are not sure that id rises when created rises) replace ORDER BY line with the following:
ORDER BY `created` DESC
Plus, in both cases, put proper indexes on: id (if it is your primary key, then there is no need to put additional index on it), sender_id and receiver_id (preferably composite index, meaning the single index for both columns), created (if you want to use ORDER BY created DESC instead of ORDER BY id DESC - otherwise there is no need for that).
try GROUP BY LEAST(sender_id, receiver_id), GREATEST(sender_id, receiver_id)