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;
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);
我们需要在SQLite中启用递归触发器:
sqlite> PRAGMA recursive_triggers = on;
创建一个临时触发以循环到范围的末尾:
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;
开始吧:
sqlite> insert into target values ((select t.startrange from t));
sqlite> select * from target;
3
2
1
sqlite>
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);
可以使用join对target执行INSERT操作:
insert into target (i)
select ints.i
from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange)
结果是这样的:
sqlite> select * from target;
i
1
2
3
当然,实际的t会有更多的行,因此需要一个WHERE子句来限制要查看t的哪一行。 类似的事情也经常发生在日期上(查阅"日历表")。 所以如果你的范围很小(对于 * small * 的某些定义),那么生成一次ints表,给它添加一个索引,然后使用上面的技术在数据库内部完成所有的INSERT。其他数据库有自己的方法(比如PostgreSQL的generate_series)来完成这类事情,而不需要显式的ints表,但是SQLite(有意地)受到限制。 SQL通常是基于集合的,所以循环是不自然的。自然的是通过描述你需要什么来构建适当的集合。当然,有时不自然的行为是必要的和明智的。 我不知道这对您的应用程序是否有意义,我只是想演示一下如何做到这一点。如果这种方法在您的情况下没有意义,那么您可以在数据库外部生成一堆INSERT语句。
3条答案
按热度按时间h5qlskok1#
显然,SQLite中的循环构造是WITH RECURSIVE子句。该文档链接包含计数到10的示例代码、Mandelbrot集合绘图器和Sudoku难题求解器,所有这些都使用纯SQL编写。下面是一个计算Fibonacci序列的SQLite查询,给予您了解一下它:
这是一个Sieve of Eratosthenes:
jchrr9hc2#
可以使用递归触发器在SQL中创建循环。使用 *mu的模式太短
我们需要在SQLite中启用递归触发器:
创建一个临时触发以循环到范围的末尾:
开始吧:
a0x5cqrl3#
如果您有一个额外的表来保存您需要的所有整数,那么您可以在直接SQL中完成这类操作。
假设
StartRange
和EndRange
的取值范围在1到10之间,那么你有一个如下的表:这个表包含了你需要的所有可能的整数(例如1到10)。
如果你还有这个
可以使用join对
target
执行INSERT操作:结果是这样的:
当然,实际的
t
会有更多的行,因此需要一个WHERE子句来限制要查看t
的哪一行。类似的事情也经常发生在日期上(查阅"日历表")。
所以如果你的范围很小(对于 * small * 的某些定义),那么生成一次
ints
表,给它添加一个索引,然后使用上面的技术在数据库内部完成所有的INSERT。其他数据库有自己的方法(比如PostgreSQL的generate_series
)来完成这类事情,而不需要显式的ints
表,但是SQLite(有意地)受到限制。SQL通常是基于集合的,所以循环是不自然的。自然的是通过描述你需要什么来构建适当的集合。当然,有时不自然的行为是必要的和明智的。
我不知道这对您的应用程序是否有意义,我只是想演示一下如何做到这一点。如果这种方法在您的情况下没有意义,那么您可以在数据库外部生成一堆INSERT语句。