ORACLE SQL:获取两个数字之间的所有整数

时间:2009-09-21 10:04:45

标签: sql oracle numbers

有没有办法在Oracle中用SQL选择两个数字之间包含的数字(整数);我不想创建PL / SQL过程或函数。

例如,我需要得到3到10之间的数字。结果将是值3,4,5,6,7,8,9,10。

THX。

13 个答案:

答案 0 :(得分:51)

Oracle的DUAL表的这个技巧也有效:

SQL> select n from
  2  ( select rownum n from dual connect by level <= 10)
  3  where n >= 3;

         N
----------
         3
         4
         5
         6
         7
         8
         9
        10

答案 1 :(得分:5)

我在创建新数据库时所做的第一个事情是创建并填充一些基本表。

一个是-N和N之间所有整数的列表,另一个是过去5年到未来10年的日期列表(预定作业可以继续根据需要继续创建这些日期)和最后一个日期是全天所有小时的列表。例如,inetgers:

create table numbers (n integer primary key);
insert into numbers values (0);
insert into numbers select n+1 from numbers; commit;
insert into numbers select n+2 from numbers; commit;
insert into numbers select n+4 from numbers; commit;
insert into numbers select n+8 from numbers; commit;
insert into numbers select n+16 from numbers; commit;
insert into numbers select n+32 from numbers; commit;
insert into numbers select n+64 from numbers; commit;
insert into numbers select n+128 from numbers; commit;
insert into numbers select n+256 from numbers; commit;
insert into numbers select n+512 from numbers; commit;
insert into numbers select n+1024 from numbers; commit;
insert into numbers select n+2048 from numbers; commit;
insert into numbers select n+4096 from numbers; commit;
insert into numbers select n+8192 from numbers; commit;
insert into numbers select -n from numbers where n > 0; commit;

这适用于具有自动事务启动的DB2 / z,这就是为什么它似乎有裸提交。

是的,它占用(最小)空间,但只需从这些表中选择值,就可以更轻松地编写查询 。它几乎可以移植到基于SQL的任何基于SQL的DBMS。

您的特定查询将很简单:

select n from numbers where n >=3 and n <= 10;

小时数字和日期范围对我们处理的报告应用程序非常有用。它允许我们为那些没有任何实际数据的那些小时(或日期)创建零条目,而不是(当月的第二天没有数据时):

Date       | Quantity
-----------+---------
2009-01-01 |        7
2009-01-03 |       27
2009-01-04 |        6

我们可以改为:

Date       | Quantity
-----------+---------
2009-01-01 |        7
2009-01-02 |        0
2009-01-03 |       27
2009-01-04 |        6

答案 2 :(得分:4)

SQL> var N_BEGIN number
SQL> var N_END number
SQL> exec :N_BEGIN := 3; :N_END := 10

PL/SQL procedure successfully completed.

SQL>  select :N_BEGIN + level - 1 n
  2     from dual
  3  connect by level <= :N_END - :N_BEGIN + 1
  4  /

         N
----------
         3
         4
         5
         6
         7
         8
         9
        10

8 rows selected.

这与Tony的使用方法相同。请注意,当您使用SQL * Plus 9时,必须像Tony向您展示的那样使此查询成为内联视图。在SQL * Plus 10或更高版本中,上述内容就足够了。

此致 罗布。

答案 3 :(得分:4)

您可以使用MODEL子句。

SELECT c1 from dual
  MODEL DIMENSION BY (1 as rn)  MEASURES (1 as c1)
  RULES ITERATE (7)
  (c1[ITERATION_NUMBER]=ITERATION_NUMBER+7)

答案 4 :(得分:2)

此单行查询将为您提供帮助,

select level lvl from dual where level<:upperbound and 

                              level >:lowerbound connect by level<:limt

对于你的情况:

select level lvl from dual where level<10 and level >3 connect by level<11

如果有任何澄清,请告诉我。

答案 5 :(得分:1)

或者您可以使用

Select Column1 from dummy_table where Column2 Between 3 and 10

答案 6 :(得分:1)

Gary,为了显示他解释的结果,模型查询将是:

选择c1 来自双重 模型尺寸乘以(1为rn)
措施(1为c1) 规则ITERATE(8) (C1 [ITERATION_NUMBER] = ITERATION_NUMBER + 3) ORDER BY rn

;)

我总是使用:

SELECT(LEVEL - 1)+ 3作为结果 从双重 CONNECT BY等级&lt; = 8

其中3是起始编号,8是“迭代次数”。

答案 7 :(得分:1)

这是一个迟到的补充。但解决方案似乎更优雅,更易于使用。

它使用必须安装一次的流水线功能:

CREATE TYPE number_row_type AS OBJECT 
(
  num NUMBER
);

CREATE TYPE number_set_type AS TABLE OF number_row_type;

CREATE OR REPLACE FUNCTION number_range(p_start IN PLS_INTEGER, p_end IN PLS_INTEGER)
    RETURN number_set_type
    PIPELINED
IS
    out_rec number_row_type := number_row_type(NULL);

BEGIN
  FOR i IN p_start .. p_end LOOP
    out_rec.num := i;
    pipe row(out_rec);
  END LOOP;

END number_range;
/

然后你可以像这样使用它:

select * from table(number_range(1, 10));

NUM
---
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

解决方案是Oracle特定的。

答案 8 :(得分:1)

从范围生成数字的一种方法是使用XMLTABLE('start to end')

SELECT column_value
FROM XMLTABLE('3 to 10');

<强> DBFiddle Demo

答案 9 :(得分:0)

我只是在SQL服务器上执行了一个表值函数,如果有人感兴趣,这可以完美地运行。

CREATE FUNCTION [dbo].[NumbersBetween]
(
    @StartN int,
    @EndN int
)
RETURNS 
@NumberList table
(
    Number int
)

AS

BEGIN

WHILE @StartN <= @EndN
    BEGIN
    insert into @NumberList
    VALUES (@StartN)
    set @StartN = @StartN + 1
    END

Return

END
GO

如果你运行查询:“select * from dbo.NumbersBetween(1,5)”(当然没有引号),结果将是

Number
-------
1
2
3
4
5

答案 10 :(得分:0)

我想分享一个有用的查询,用于转换逗号字符串和&#39; - &#39;将分隔的数字列表分成等效的扩展数字列表:

转换&#1,2; 1,2,50-60&#39;进入

1
2
3
50
51
...
60
select distinct * from (SELECT (LEVEL - 1) + mini as result FROM (select REGEXP_SUBSTR (value, '[^-]+', 1, 1)mini ,nvl(REGEXP_SUBSTR (value, '[^-]+', 1, 2),0) maxi from (select REGEXP_SUBSTR (value, '[^,]+', 1, level) as value from (select '1,2,3,50-60' value from dual) connect by level <= length(regexp_replace(value,'[^,]*'))+1)) CONNECT BY Level <= (maxi-mini+1)) order by 1 asc;

您可以将其用作视图并参数化1,2,3,50-60&#39;串

答案 11 :(得分:0)

create table numbers (value number);

declare
    x number;
begin
    for x in 7 .. 25
    loop
        insert into numbers values (x);
    end loop;
end;
/

答案 12 :(得分:0)

除了已经提供的答案外,还可以将listagg函数与connect by结合使用,以问题中提到的格式获得结果。请参见下面的代码示例:

SELECT 
   DBMS_LOB.SUBSTR(LISTAGG(S.INTEGERS,',' ) WITHIN GROUP (ORDER BY S.INTEGERS), 300,1) RESULT 
FROM 
   (SELECT 
      INTEGERS 
   FROM 
      ( SELECT ROWNUM INTEGERS FROM DUAL CONNECT BY LEVEL <= 10) 
   WHERE 
      INTEGERS >= 3 
   ) S;

输出:

SQL> 
RESULT
----------------
3,4,5,6,7,8,9,10