我需要得到一个包含前N个正整数的结果集。是否可以仅使用标准SQL SELECT语句来获取它们(不提供任何计数表)?
如果不可能,是否有任何特定的MySQL方法来实现这一目标?
答案 0 :(得分:16)
似乎你想要的是dummy rowset
。
在MySQL
中,没有桌子就不可能。
大多数主要系统提供了一种方法:
在Oracle
:
SELECT level
FROM dual
CONNECT BY
level <= 10
在SQL Server
:
WITH q AS
(
SELECT 1 AS num
UNION ALL
SELECT num + 1
FROM q
WHERE num < 10
)
SELECT *
FROM q
在PostgreSQL
:
SELECT num
FROM generate_series(1, 10) num
MySQL
缺少类似的东西,这是一个严重的缺点。
我写了一个简单的脚本来为我的博客文章中的示例表生成测试数据,也许它会有用:
CREATE TABLE filler (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
) ENGINE=Memory;
CREATE PROCEDURE prc_filler(cnt INT)
BEGIN
DECLARE _cnt INT;
SET _cnt = 1;
WHILE _cnt <= cnt DO
INSERT
INTO filler
SELECT _cnt;
SET _cnt = _cnt + 1;
END WHILE;
END
$$
你打电话给程序,表格里面都填满了数字。
您可以在会话期间重复使用它。
答案 1 :(得分:10)
一种可能的解决方案(当然不是很优雅)是使用任何具有足够大量记录的表。
对于前10个整数(使用mysql.help_relation,但任何表都可以),您可以使用以下查询:
SELECT @N := @N +1 AS integers
FROM mysql.help_relation , (SELECT @N:=0) dum LIMIT 10;
这也可以放在Min和Max的函数中。
答案 2 :(得分:4)
奇怪的解决方案,但是......
SELECT 1 UNION SELECT 2 UNION SELECT 3....
答案 3 :(得分:4)
我建议的序列允许程序员执行以下查询:
select value from sequence where value>=15 and value<100;
并获得预期的结果:15(包括)和100(不包括)之间的整数序列。
如果这是您想要的,您将必须创建以下两个视图,您只需声明一次的视图:
create view digits as select 0 n union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9;
create view sequence as select u.n+t.n*10+h.n*100 as value from digits as u cross join digits as t cross join digits as h;
通过这种方式,您可以使用直观的SELECT ...
希望它有所帮助。
答案 4 :(得分:2)
假设你的意思是从表中检索它们,这里N是10,假设intcolumn是包含数字的列。
SELECT intcolumn FROM numbers WHERE intcolumn > 0 LIMIT 10
编辑:如果您实际上想要获得没有表格的正数数学集合,我会重新考虑,它可能是密集的(取决于实现)。通常接受的做法似乎是创建一个包含数字的查找表,然后使用上面的查询。
答案 5 :(得分:1)
这可能会有所帮助
获得i <= R <1的范围内的随机整数R. j,使用表达式FLOOR(i + RAND()*(j-i))。例如,为了获得范围7 <= R <1的范围内的随机整数。 12,您可以使用以下语句:
SELECT FLOOR(7 + (RAND() * 5));
答案 6 :(得分:1)
如果你知道N
是有限的(通常是),你可以使用如下结构:
select (a.digit + (10 * b.digit) + (100 * c.digit) + (1000 * d.digit) + (10000 * e.digit) + (100000 * f.digit)) as n
from (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as e
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as f;
将产生第一百万个数字。如果您只需要正数,只需将+ 1
添加到表达式。
请注意,特别是在MySQL中,结果可能无法排序。如果您需要订购号码,则需要将order by n
追加到最后。这会大大增加执行时间,但是(在我的机器上,它从5毫秒跳到500毫秒)。
对于简单查询,这里只查询前10000个数字:
select (a.digit + (10 * b.digit) + (100 * c.digit) + (1000 * d.digit)) as n
from (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
cross join (select 0 as digit union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d;
此答案改编自以下返回日期范围的查询:https://stackoverflow.com/a/2157776/2948
答案 7 :(得分:0)
看看以下SO问题:
修改强>
另一个方法是创建一个为您执行此操作的存储过程。 PostgreSQL包含一个函数generate_series(start,stop),可以完成你想要的任务。
select * from generate_series(2,4);
generate_series
-----------------
2
3
4
(3 rows)
我不熟悉MySQL,但如果你对SP没问题,那么这样的事情应该很容易实现。 This网站显示了一个实现。
答案 8 :(得分:0)
如果我理解你的问题,我很确定你不能这样做。
据我所知,您需要从单个SQL语句中获取列表,而不必引用特定的表吗?
我很确定在任何SQL方言中都不可能。如果你得到一个顺序递增的数字以及另一个查询的结果,那么这是可能的(取决于SQL方言,在mssql上它将是rownumber(),但我不知道如何在MySql中,但它可能有)
但那不是我听到你问的那个?
答案 9 :(得分:0)
如果您的数据库支持分析窗口函数,则以下操作非常简单:
SELECT row_number() over (partition by 1 order by 1) numbers
FROM SOME_TABLE
LIMIT 2700;
此语句返回1到2700之间的一组数字。