I have a user_profile_view table:
The definition is as follows:
+------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| user_id | bigint(20) | NO | MUL | NULL | |
| viewer_id | bigint(20) | NO | MUL | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+------------+------------+------+-----+---------+----------------+
I’m trying to get the most recent visits but I only want to display the user once
A simple query such as this will return the most recent visits on a profile:
SELECT v.* FROM user_profile_view v
WHERE v.user_id != 1 AND v.viewer_id = 1
ORDER BY created_at DESC LIMIT 0,10;
The result set:
+-----+---------+-----------+---------------------+---------------------+
| id | user_id | viewer_id | created_at | updated_at |
+-----+---------+-----------+---------------------+---------------------+
| 946 | 19 | 1 | 2011-10-05 19:20:19 | 2011-10-05 19:20:19 |
| 945 | 19 | 1 | 2011-10-05 19:16:15 | 2011-10-05 19:16:15 |
| 944 | 2 | 1 | 2011-10-05 19:12:02 | 2011-10-05 19:12:02 |
| 943 | 13 | 1 | 2011-10-05 19:11:45 | 2011-10-05 19:11:45 |
| 942 | 19 | 1 | 2011-10-05 19:10:41 | 2011-10-05 19:10:41 |
| 941 | 2 | 1 | 2011-10-05 19:06:35 | 2011-10-05 19:06:35 |
| 940 | 19 | 1 | 2011-10-05 18:53:04 | 2011-10-05 18:53:04 |
| 939 | 19 | 1 | 2011-10-05 18:51:56 | 2011-10-05 18:51:56 |
| 938 | 19 | 1 | 2011-10-05 18:46:59 | 2011-10-05 18:46:59 |
| 937 | 20 | 1 | 2011-10-05 18:42:35 | 2011-10-05 18:42:35 |
+-----+---------+-----------+---------------------+---------------------+
However I only want to return the user once. So if I have recently viewed a users profile 3 times, I only want the most recent visit to that profile and then display the next user who I visited before.
This should be trivial but for some reason I’m stuck.
Thanks folks!
It’s not actually trivial. This is a “greatest-N-per-group” problem. Some variants of SQL have added windowing functions to handle this, I’m not sure whether MySQL has or not.
To do this without windowing functions you can test each potential answer to see if there exists in the same table a row for the same user_id but a more recent created_at time):
Note that ties (two records with the exact same created_at value) will return both rows.