sqlsqliteloopsfor-looprange

SQLite loop statements?


Is there any loop statements in SQLite like FOR .. in .. LOOP or something like that? I have two columns StartRange, EndRange and I need to insert a whole sequence in the other table. So if StartRange is 1 and EndRange is 3 it's necessary to make three inserts with the values 1, 2, 3.


Solution

  • You can do this sort of thing in straight SQL if you have an extra table that holds all the integers that you need.

    Suppose your StartRange and EndRange range between one and ten and you have a table like this:

    sqlite> select i from ints;
    i
    1
    .
    .
    .
    10
    

    This table simply contains all the possible integers that you need (i.e. one through ten).

    Then if you also have this:

    sqlite> create table t (startrange int not null, endrange int not null);
    sqlite> insert into t values(1, 3);
    sqlite> create table target (i int not null);
    

    You can do your INSERTs into target with a join:

    insert into target (i)
    select ints.i
    from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange)
    

    The result is this:

    sqlite> select * from target;
    i
    1
    2
    3
    

    Of course your real t would have more rows so you'd want a WHERE clause to limit which row of t you look at.

    Similar things are often done with dates (look up "calendar tables").

    So if your ranges are small (for some definition of small) then generate your ints table once, add an index to it, and use the above technique to do all the INSERTs right inside the database. Other databases have their own ways (such as PostgreSQL's generate_series) to do this sort of thing without need an explicit ints table but SQLite is (intentionally) limited.

    SQL is generally set-based so loops aren't natural. What is natural is building the appropriate sets by describing what you need. OTOH, sometimes unnatural acts are necessary and sensible.

    I don't know if this makes sense for your application, I just thought I'd demonstrate how it can be done. If this approach doesn't make sense in your case then you can generate a bunch of INSERT statements outside the database.