SQLite循环语句?

kse*_*een 22 sql sqlite loops for-loop range

在SQLite中是否有类似的循环语句FOR .. in .. LOOP?我有两列StartRange, EndRange,我需要在其他表中插入整个序列.因此,如果StartRange是1并且EndRange是3,则需要使用值包含三个插入1, 2, 3.

Dou*_*rie 19

您可以使用递归触发器在SQL中创建循环.使用mu太短的架构

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);
Run Code Online (Sandbox Code Playgroud)

我们需要在SQLite中启用递归触发器:

sqlite> PRAGMA recursive_triggers = on;
Run Code Online (Sandbox Code Playgroud)

制作一个临时触发器以循环到范围的末尾:

sqlite> create temp trigger ttrig
   ...> before insert on target
   ...> when new.i < (select t.endrange from t) begin
   ...> insert into target values (new.i + 1);
   ...> end;
Run Code Online (Sandbox Code Playgroud)

开始吧:

sqlite> insert into target values ((select t.startrange from t));
sqlite> select * from target;
3
2
1
sqlite> 
Run Code Online (Sandbox Code Playgroud)

  • 这是我需要的黑魔法.谢谢哥们儿! (2认同)
  • 对于大范围,这会导致“触发递归级别过多” (2认同)

mu *_*ort 11

如果你有一个包含你需要的所有整数的额外表,你可以在直接SQL中执行此类操作.

假设你StartRangeEndRange一个十之间的范围,你有这样的一个表:

sqlite> select i from ints;
i
1
.
.
.
10
Run Code Online (Sandbox Code Playgroud)

该表只包含您需要的所有可能的整数(即1到10).

如果你也有这个:

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);
Run Code Online (Sandbox Code Playgroud)

您可以使用联接进行INSERT target:

insert into target (i)
select ints.i
from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange)
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

sqlite> select * from target;
i
1
2
3
Run Code Online (Sandbox Code Playgroud)

当然你的真实t会有更多行,所以你想要一个WHERE子句来限制t你看哪一行.

类似的事情通常用日期来完成(查找"日历表").

因此,如果范围很小(对于某些小的定义),则生成ints一次表,为其添加索引,并使用上述技术在数据库内部执行所有INSERT.其他数据库有自己的方式(比如PostgreSQL generate_series)来做这种事情而不需要显式ints表,但SQLite(故意)有限.

SQL通常是基于集合的,因此循环不自然.通过描述您的需求来构建适当的集合是很自然的.OTOH,有时不自然的行为是必要和明智的.

我不知道这对你的应用程序是否有意义,我只是想我会演示它是如何完成的.如果这种方法在您的情况下没有意义,那么您可以在数据库外生成一堆INSERT语句.


rob*_*rob 9

显然,SQLite中的循环结构是WITH RECURSIVE子句.该文档链接包含样本数到十的代码,一个Mandelbrot set plotter和一个Sudoku难题解算器,所有这些都在纯SQL中.这是一个SQLite查询,它计算Fibonacci序列,让您感受到它:

sqlite> WITH RECURSIVE
   ...>   fibo (curr, next)
   ...> AS
   ...>   ( SELECT 1,1
   ...>     UNION ALL
   ...>     SELECT next, curr+next FROM fibo
   ...>     LIMIT 100 )
   ...> SELECT group_concat(curr) FROM fibo;
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
Run Code Online (Sandbox Code Playgroud)

是Eratosthenes筛子:

begin transaction;

drop table if exists naturals;
create table naturals
( n integer unique primary key asc,
  isprime bool,
  factor integer);

with recursive
  nn (n)
as (
  select 2
  union all
  select n+1 as newn from nn
  where newn < 1e4
)
insert into naturals
select n, 1, null from nn;

insert or replace into naturals
  with recursive
    product (prime,composite)
  as (
    select n, n*n as sqr
      from naturals
      where sqr <= (select max(n) from naturals)
    union all
    select prime, composite+prime as prod
    from
      product
    where
      prod <= (select max(n) from naturals)
  )
select n, 0, prime
from product join naturals
  on (product.composite = naturals.n)
;
commit;
Run Code Online (Sandbox Code Playgroud)