我需要获取包含前N个正整数的结果集。是否有可能只使用标准的SQL SELECT语句来获取它们(没有提供任何计数表)?SQL SELECT获取前N个正整数
如果这是不可能的,是否有任何特定的MySQL方式来实现这一点?
我需要获取包含前N个正整数的结果集。是否有可能只使用标准的SQL SELECT语句来获取它们(没有提供任何计数表)?SQL SELECT获取前N个正整数
如果这是不可能的,是否有任何特定的MySQL方式来实现这一点?
看来,你想要的是一个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
$$
你调用过程并表被填充数字。
您可以在会话期间重复使用它。
很棒的回答。这肯定是有帮助的。 – monn 2009-09-26 19:10:58
假设您的意思是从表中检索它们,这里N是10,假设intcolumn是包含数字的列。
SELECT intcolumn FROM numbers WHERE intcolumn > 0 LIMIT 10
编辑:如果你实际上是希望得到的数学组正数的不表,我会重新考虑,也可以是密集的(取决于实现)。通常接受的做法似乎是创建一个充满数字的查找表,然后使用上述查询。
在该followhing SO问题请看:
编辑:
另一种形式给出是创建一个存储过程,这是否为你。 PostgreSQL包含一个函数generate_series(start,stop),它可以做你想做的事情。
select * from generate_series(2,4);
generate_series
-----------------
2
3
4
(3 rows)
我不熟悉MySQL,但是像这样的东西应该很容易实现,如果你对SP好的话。 This网站显示一个实施。
看起来好像这两种方法都需要某种形式的查找表(使用AUTO_INCREMENT) – Kazar 2009-09-25 08:07:43
我很肯定你不能这样做,如果我正确理解你的问题。
正如我理解你的问题,你想从单个SQL语句的列表,而不必引用特定的表?
我敢肯定,在任何SQL方言中都是不可能的。如果你要得到一个顺序递增的数字以及另一个查询的结果,那么这将是可能的(取决于SQL方言,在mssql上它将是rownumber(),但我不知道如何在MySql中,但它可能那里)
但是,这不是我听到你问?
在PostgreSQL中有一个名为generate_series(start,stop)的函数,它完全符合OP的要求。 – 2009-09-25 14:44:36
这可有助于
要获得的范围内的随机整数R I < = R <Ĵ,使用表达式FLOOR第(i + RAND()*(j - i))的。例如,为了获得在范围内7 < = R < 12,可以使用下面的语句范围内的随机整数:
SELECT FLOOR(7 + (RAND() * 5));
他在问顺序正整数。不是随机的。 – 2009-09-25 10:52:47
怪异的解决方案,但是......
SELECT 1 UNION SELECT 2 UNION SELECT 3....
我建议的顺序允许程序员执行以下查询:
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;
这样,你有一个直观的选择您的序列...
希望它有帮助。
疯了! ...它工作。我需要在视图中工作的东西 - 将分配赋值给一个变量会阻止视图。尼斯。 – 2017-07-25 01:55:27
一个可能的解决方案(当然不是很优雅)是使用任何具有足够大量记录的表。
对于第10个整数(使用mysql.help_relation,但任何表会做),你可以使用下面的查询:
SELECT @N := @N +1 AS integers
FROM mysql.help_relation , (SELECT @N:=0) dum LIMIT 10;
这也被放置在服用最小和最大的功能。
感谢您的提示。成功使用以下内容来获取日期范围:'SELECT @i:= DATE_SUB(@i,INTERVAL 1 DAY)date FROM mysql.help_relation,(SELECT @i:= CURRENT_DATE)v WHERE @i> DATE_SUB(CURRENT_DATE,INTERVAL 3个月);'。 – 2014-05-27 13:20:18
这不是一个通用的解决方案。它的工作原理是,只要你使用的表格至少有你想获得的行数。创建一个没有行的虚拟表,并且SELECT @N:= @ N + 1 AS整数FROM dummy(SELECT @N:= 0)dum LIMIT 10不产生行。 – user1645975 2014-09-02 09:36:53
可能会老了,但这太棒了。我知道这样的事情必须存在。 – slicedtoad 2015-02-26 19:53:02
如果你知道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
如果你的数据库支持分析窗口以下功能是简单的作品真的很好:
SELECT row_number() over (partition by 1 order by 1) numbers
FROM SOME_TABLE
LIMIT 2700;
此语句返回一组数字从1到2700
首先在什么defintion? – 2009-09-25 07:56:26