my goal is to return a distinct list of 'mFrom' and only pull the latest 'date' from 'messages' table..
Table: messages
id mFrom mTo date
-- ----- --- ----
int int int datetime
I am trying to use this query:
SELECT DISTINCT(mFrom), date FROM messages WHERE mTo = '116'
But am receiving these results:
mFrom date
9 | 2016-11-17 00:30:03
11 | 2016-11-17 12:35:08
11 | 2016-11-17 12:35:35
and I would like to see these results instead..
mFrom date
9 | 2016-11-17 00:30:03
11 | 2016-11-17 12:35:35
Any help is appreciated. Saw similar answers using GROUP BY and an inner SELECT but having trouble coming up with a comparable query for my specific fields..
GROUP BY seems right.
SELECT mFrom, MAX(date) as date
FROM messages
WHERE mTo = '116'
GROUP BY mFrom
Let's say you have more columns that are unique in play, eg you want the latest message from mFrom but you also want mTo as well. Then you should consider a partitioned Row Number. For systems eg sql-server that support Windows Functions typically they will have a ROW_NUMBER()
function that you can use. Here is an example using Common Table Expression [CTE] and ROW_NUMBER()
. Note using RANK() or DENSE_RANK() instead will allow for ties.
;WITH cte AS (
SELECT *
,ROW_NUMBER() OVER (PARTITION BY mFrom ORDER BY Date DESC) as RowNumber
FROM
Messages
WHERE
mTo = 116
)
SELECT *
FROM
cte
WHERE
RowNumber = 1
In my sql this becomes more complicated and you can do it via using variables:
SELECT *
FROM
(
SELECT
m.*
,(@rn:= if(@mFrom = mFrom, @rn + 1,
if(@mFrom:=mFrom, 1, 1)
)) as RowNumber
FROM
Messages m
CROSS JOIN (SELECT @mFrom:=0, @rn:=0) var
WHERE
mTo = 116
) t
WHERE
t.RowNumber = 1
Or in either system you can use the GROUP BY technique that Gareth Shows and relate it back to the original table, or IN or EXISTS all of these methods will return ties if 2 messages of mFrom share the same MAX(date). here is an example with a join.
SELECT *
FROM
Messages m
INNER JOIN (SELECT mFrom, MAX(date) as date
FROM
Messages
WHERE
mTo = 116
GROUP BY
mFrom) t
ON m.mFrom = t.mFrom
AND m.date = t.date
WHERE
mTo = 116
11 | 2016-11-17 12:35:08
11 | 2016-11-17 12:35:35
you can see the date time field, time is off by couple of seconds.
You can do is,
SELECT DISTINCT(mFrom), cast(date as date) FROM messages WHERE mTo = '116'
This will remove the time and give you
mFrom date
9 | 2016-11-17
11 | 2016-11-17
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.