Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rolling rows in SQL table

Tags:

sql

sqlite

I'd like to create an SQL table that has no more than n rows of data. When a new row is inserted, I'd like the oldest row removed to make space for the new one.

Is there a typical way of handling this within SQLite?

Should manage it with some outside (third-party) code?

like image 463
David Parr Avatar asked Dec 29 '09 22:12

David Parr


People also ask

How do I rearrange rows in SQL?

You can change the order of the rows by adding an ORDER BY clause at the end of your query, with a column name after. By default, the ordering will be in "ascending order", from lowest value to highest value. To change that to "descending order", specify DESC after the column name.

How do I make multiple rows in one row in SQL?

You can concatenate rows into single string using COALESCE method. This COALESCE method can be used in SQL Server version 2008 and higher. All you have to do is, declare a varchar variable and inside the coalesce, concat the variable with comma and the column, then assign the COALESCE to the variable.

How do I select multiple rows in a single column in SQL?

In this case, we use GROUP_CONCAT function to concatenate multiple rows into one column. GROUP_CONCAT concatenates all non-null values in a group and returns them as a single string. If you want to avoid duplicates, you can also add DISTINCT in your query.


2 Answers

Expanding on Alex' answer, and assuming you have an incrementing, non-repeating serial column on table t named serial which can be used to determine the relative age of rows:

 CREATE TRIGGER ten_rows_only AFTER INSERT ON t
   BEGIN
     DELETE FROM t WHERE serial <= (SELECT serial FROM t ORDER BY serial DESC LIMIT 10, 1);
   END;

This will do nothing when you have fewer than ten rows, and will DELETE the lowest serial when an INSERT would push you to eleven rows.

UPDATE

Here's a slightly more complicated case, where your table records "age" of row in a column which may contain duplicates, as for example a TIMESTAMP column tracking the insert times.

sqlite> .schema t
CREATE TABLE t (id VARCHAR(1) NOT NULL PRIMARY KEY, ts TIMESTAMP NOT NULL);
CREATE TRIGGER ten_rows_only AFTER INSERT ON t
  BEGIN
    DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY ts DESC LIMIT 10, -1);
  END;

Here we take for granted that we cannot use id to determine relative age, so we delete everything after the first 10 rows ordered by timestamp. (SQLite imposes an arbitrary order on rows sharing the same ts).

like image 85
pilcrow Avatar answered Sep 27 '22 23:09

pilcrow


Seems SQLite's support for triggers can suffice: http://www.sqlite.org/lang_createtrigger.html

like image 42
Alex Brasetvik Avatar answered Sep 27 '22 21:09

Alex Brasetvik