SQL:从“无”中选择数字列表
什么是一种快速/可读的方法,可以从无中选择包含数字列表的关系。我想通过设置起始值和结束值来定义哪些数字。我正在使用Postgres SQL和SQLite,并且对能够在这两种/多种平台上工作的通用解决方案感兴趣 期望输出关系:SQL:从“无”中选择数字列表,sql,sqlite,postgresql,sequence,Sql,Sqlite,Postgresql,Sequence,什么是一种快速/可读的方法,可以从无中选择包含数字列表的关系。我想通过设置起始值和结束值来定义哪些数字。我正在使用Postgres SQL和SQLite,并且对能够在这两种/多种平台上工作的通用解决方案感兴趣 期望输出关系: # x 0 1 2 3 4 我知道我可以从无到有地选择一行:选择0,1,2,3,4,但这会将值选择为列而不是行,并且需要指定查询中的所有值,而不是仅使用起始值和结束值:0和4 在Postgres中,对于这种情况,您有一个特殊的generate_seri
# x
0
1
2
3
4
我知道我可以从无到有地选择一行:选择0,1,2,3,4,但这会将值选择为列而不是行,并且需要指定查询中的所有值,而不是仅使用起始值和结束值:0和4
在Postgres中,对于这种情况,您有一个特殊的generate_series函数:
SELECT * FROM generate_series(0,4) x;
这很好地工作,但不是标准的。我还可以想象一些使用临时表的复杂解决方案,但我希望有一些通用且简单的解决方案,如:
SELECT * FROM [0..4]
也许在SQL server和PostgreSQL中使用SEQUENCE语句或SELECT 0和SELECT 4的神奇组合?我会使用递归公共表表达式: 但是,据我所知,SQLite中没有WITH 因此,可能的解决办法是 创建一个用户定义的函数可能会有所帮助 创建一个表,表中的数字从0到所需的最大数字,然后按如下方式选择:
select Number from Numbers where Number >= 0 and Number <= 4
在PostgreSQL和SQLite中执行此操作的简单方法如下:
sqlite> select 1 union select 2 union select 3;
1
2
3
它应该可以在大多数RDBMS系统中使用,但在Oracle中,您必须使用IIRC:
select 1 from dual union select 2 from dual union select 3 from dual;
但是我没有Oracle DB来测试它。谢谢所有的答案!
在讨论之后,我意识到使用a并不太复杂,在两种/多种平台上都能很好且快速地工作:
CREATE TABLE integers (i integer);
INSERT INTO integers (i) VALUES (0);
INSERT INTO integers (i) VALUES (1);
...
INSERT INTO integers (i) VALUES (9);
SELECT (hundreds.i * 100) + (tens.i * 10) + units.i AS x
FROM integers AS units
CROSS JOIN integers AS tens
CROSS JOIN integers AS hundreds
您只需创建一次此表,并可以在需要一系列数字时使用它。其他一些替代方法在postgres中尝试过,但应该与其他方法一起使用 选择0作为计数联合值1,2,3,4,5
用代码扩展这个sql很简单。递归CTE也可以在Postgres中使用,事实上,这是唯一的标准方法-因为现在几乎所有现代DBMS都支持递归CTE,所以我刚刚尝试帮助使用SQLite,因为他知道如何在PostgreSQL中使用它,但谢谢,我将编辑答案虽然递归CTE可以在大多数现代DBMS中工作,但它已被证明是有效的。我认为数字表是目前为止最好的方法。@GarethD是的,在我的生产代码中,我使用数字表来表示未知的数字范围datesThx,作为数字表的提示,一些进一步的研究表明,您可以从这个基表交叉连接更多的范围。请看我的编辑,我想你最好使用1000以下的数字——也许可以在表上放一个索引。否则,创建一些视图,如numbers\u to\u 1000、numbers\u to\u 1000000来封装这些交叉连接。@尤文图斯,你能接受一些答案吗?或者发布你的答案并接受它吗?当我开始寻找时,我惊讶于这个看似简单的任务是多么的笨拙。这里有一篇文章提供了更多的可能性,但它建议没有任何东西可以从PostgreSQL生成U系列:很多想法都不是像BigQuery这样的只读环境的选项。
CREATE TABLE integers (i integer);
INSERT INTO integers (i) VALUES (0);
INSERT INTO integers (i) VALUES (1);
...
INSERT INTO integers (i) VALUES (9);
SELECT (hundreds.i * 100) + (tens.i * 10) + units.i AS x
FROM integers AS units
CROSS JOIN integers AS tens
CROSS JOIN integers AS hundreds