I've got a table that contains (let's say) all the times when a user looked at a specific webpage. Users can of course look at a page more than once, so there can be multiple entries for users and pages, like so:
nid time user page_id
25 8000 4 467
24 7000 1 482
23 6000 1 484
22 5000 1 482
21 4000 5 467
20 3000 4 467
I want to do a query that returns the rows corresponding to every page viewed by every user WITH THE CATCH THAT if a user looked at a page more than once, I get the row corresponding to the most recent view (i.e., the largest value of TIME). Thus, I should get this:
nid time user page_id
25 8000 4 467
24 7000 1 482
23 6000 1 484
21 4000 5 467
We lose row 22 because user 1 looked at page 482 at a later time, and we lose row 20 because user 4 looked at page 467 at a later time.
I almost have this figured out, but I can't quite crack it, while also convincing myself that the results I'm getting will be generally correct and not just an accident of my test cases. I keep going back and forth between GROUP BY or DISTINCT queries and embedded queries, and then my brain explodes. Any suggestions? Thanks!
MySQL MAX() function with GROUP BY retrieves maximum value of an expression which has undergone a grouping operation (usually based upon one column or a list of comma-separated columns).
To find the maximum value of a column, use the MAX() aggregate function; it takes a column name or an expression to find the maximum value. In our example, the subquery returns the highest number in the column grade (subquery: SELECT MAX(grade) FROM student ).
When issuing a query with SELECT , you can end it with GROUP BY to group the selected columns by a particular column value. This is typically used in combination with aggregate functions, so that the results show the result of some aggregation function for rows with particular column values.
We used the MAX() function within a subquery to find the maximum value, and returned the whole row with the outer query.
If you need the full row you can use this:
SELECT fullTable.nid as nid,
recent.time as time,
fullTable.user as user,
fullTable.page_id as page_id
FROM TableName fullTable
INNER JOIN (SELECT MAX(t1.time) as time, t1.user, t1.page_id
FROM TableName t1
GROUP BY user, page_id) recent
ON recent.time = fullTable.time AND
recent.user = fullTable.user AND
recent.page_id = fullTable.page_id
ORDER BY time DESC
If you ask for a column outside the "group by" clause, mysql can return any value for this column inside this group. So if all the values inside the group are not the same, that is your case, you can't include it directly on the select clause, you need to use a join.
You can read more about not grouped columns on MySQL on the reference
If you don't need the nid field, you can use this other:
SELECT MAX(time) as time, user, page_id
FROM TableName
GROUP BY user, page_id
ORDER BY time DESC
Try this:
SELECT *
FROM <YOUR_TABLE>
WHERE (user, page_id, time) IN
(
SELECT user, page_id, MAX(time) time
FROM <YOUR_TABLE>
GROUP BY user, page_id
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With