0

I have a database with "num" table like this

user_id  |  number   |  unix_time
-----------------------------
123         2           xxxxxxxx
123         40          xxxxxxxx
123         24          xxxxxxxx
333         23          xxxxxxxx
333         67          xxxxxxxx
854         90          xxxxxxxx

I'd like to select the last 5 numbers inserted by each user_id, but I can't figure out how to do it.

I tried:

SELECT b.n, a.user_id
FROM num a
JOIN num b on a.user_id = b.user_id
WHERE (
    SELECT COUNT(*)
    FROM num b2
    WHERE b2.n <= b.n
        AND b2.user_id = b.user_id
) <= 5
CL.
  • 173,858
  • 17
  • 217
  • 259
Daniele
  • 11
  • 1
  • Welcome to StackOverflow. Please take the tour stackoverflow.com/tour, learn asking good questions stackoverflow.com/help/how-to-ask, make a MCVE stackoverflow.com/help/mcve For SQLite, an MCVE includes a `.dump` of your SQLite database. – Yunnosch Apr 17 '17 at 15:14
  • What do you mean by "last"? Most recent according to column "unix_time"? Then you should provide sample data with appropriate times. – Yunnosch Apr 17 '17 at 15:19

2 Answers2

0

I am adapting the answer from (sql query - how to apply limit within group by).
I use "2" instead of "5" to make the effect visible within your sample data.
Note that I used actual dates instead of your "xxxxxxxx", assuming that most likely you mean "most recent 5" when you write "last 5" and that only works for actual times.

select * from toy a
    where a.ROWID IN  
    ( SELECT b.ROWID FROM toy b
      WHERE b.user_id = a.user_id
      ORDER by unix_time DESC 
      LIMIT 2 
    ) ;

How is it done:

  • make on-the-fly tables (i.e. the part within ())
  • one for each user_id, WHERE b.user_id = a.user_id
  • order each on-the-fly table separatly (that is the first trick),
    by doing the ordering inside the ()
  • order chronologically backwards ORDER by unix_time DESC
  • limit to 5 (in the example 2) entries LIMIT 2
  • limit each on-the-fly table separatly (that is the second trick),
    by doing the limiting inside the ()
  • select everything from the actual table, select * from toy,
    but only select from the actual table those lines which occur in the total of all on-the-fly tables,
    where a.ROWID IN (

  • introduce the distinguishing alias "a" for the total view of the table,
    toy a

  • introduce the distinguishing alias "b" for the single-user_id view of the table,
    toy b

By the way, here is the dump of what I used for testing
(it is a convenient way of making most of a MCVE):

BEGIN TRANSACTION;
CREATE TABLE toy (user_id int, number int, unix_time date);
INSERT INTO toy VALUES(123,2,'1970-01-01 05:33:20');
INSERT INTO toy VALUES(123,40,'1970-01-01 06:56:40');
INSERT INTO toy VALUES(123,24,'1970-01-01 08:20:00');
INSERT INTO toy VALUES(333,23,'1970-01-01 11:06:40');
INSERT INTO toy VALUES(333,67,'1970-01-01 12:30:00');
INSERT INTO toy VALUES(854,90,'1970-01-01 13:53:20');
COMMIT;
Community
  • 1
  • 1
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
0

If you want to select last 5 records from the SQlite database then use query SELECT * FROM table_name ORDER BY user_id DESC LIMIT 5; Using this query you can select last n transactions...Hope I helped you

Bhupesh Kumar
  • 240
  • 2
  • 14