Sorry if it's a dubplicate but I can't find an answer to the question.
Hello there so I have three tables users and articles and likes, a user can write an article, in the table articles there is also a timestamp column and can be liked by other users where a like is saved in likes table with the user id and secret id.
articles table:
+----+---------+--------------------+
| id | article | timestamp |
+----+---------+--------------------+
| 1 | A |2019-02-10 22:19:02 |
| 2 | B |2019-02-9 22:20:28 |
| 3 | C |2019-02-9 22:21:10 |
| 4 | D |2019-02-8 18:20:10 |
| 5 | E |2019-02-8 13:25:04 |
+----+---------+--------------------+
likes table:
+-----------+--------+
| articleid | userid |
+-----------+--------+
| 1 | 1 |
| 1 | 3 |
| 1 | 5 |
| 1 | 3 |
| 2 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 3 | 5 |
| 3 | 2 |
| 4 | 4 |
+-----------+--------+
I'm trying to do the pagination of the most liked articles in the shortest time,
as for example in this case article A is the top of the order because it got more likes in less time,
How would I do that and at the same time LIMIT the result to do the pagination?
My try was:
SELECT * FROM articles, (SELECT count(*) FROM likes WHERE articleid = id) as likes
GROUP BY articles
OREDER BY likes
LIMIT 10
I would do it in php without LIMIT but at the same time I want to repeat the query to get the next articles for the second page in the same way and I have no idea how to do that.
Thanks in advance!
Best Answer
Once the database is more than a 'toy', you will need to keep an up-to-date (or nearly so) table of actual like-counts. It would have two columns: article_id and like_ct with
article_id
as the PK.With that (plus a
JOIN
) you can do an efficient pagination withoutOFFSET
.Start with a 2-column table:
This should give you the list of article_ids ordered by most likes in the last 2 days, counting back from the instant the query was run.
With
LIMIT 10
you can get the top 10. WithOFFSET
you can inefficiently get other 'pages'.Use the above as a "derived" table and
JOIN Articles USING(article_id)
to get other info.