SQL Query从dual返回N行

时间:2009-12-29 09:14:19

标签: sql oracle plsql

我想编写一个接受绑定变量(例如:NUM)的SQL查询,其输出包含一列& :NUM行数,每行具有行号。即如果我们传递:NUM为7,则输出应为:

VAL
====
1
2
3
4
5
6
7

查询中不应该有任何实际的DB表,也不应该使用PL / SQL代码。即在查询中只应使用双重

有没有办法实现这个目标?

10 个答案:

答案 0 :(得分:34)

您可以使用:

 WHERE ROWNUM <= :NUM

...但是该表必须包含与bind变量中的限制相等或更大的行。 This link demonstrates various row number generation techniques in Oracle

使用CONNECT BY,Oracle 10g +:

SELECT LEVEL
  FROM DUAL
CONNECT BY LEVEL <= :NUM

monojohnny确认可以使用绑定变量。虽然支持CONNECT BY语法,但尝试在Oracle 9i上运行会导致ORA-01436错误。

我唯一不能100%开启的是CONNECT BY是否接受绑定变量的限制。

参考:

答案 1 :(得分:4)

尝试类似:

SELECT 1 AS Val FROM dual
UNION ALL SELECT 2 FROM dual
UNION ALL SELECT 3 FROM dual
UNION ALL SELECT 4 FROM dual
UNION ALL SELECT 5 FROM dual
UNION ALL SELECT 6 FROM dual
UNION ALL SELECT 7 FROM dual;

它很乱,但它会起作用。

编辑:啊 - 你需要传递一个变量来让你知道要走多远......

那么如下:

SELECT t1.Val + t2.Val * 2 + t3.Val * 4 + t4.Val * 8 AS Val
FROM
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t1, 
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t2, 
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t3, 
(
SELECT 0 AS Val FROM dual
UNION ALL SELECT 1 FROM dual
) AS t4
WHERE t1.Val + t2.Val * 2 + t3.Val * 4 + t4.Val * 8 <= 7;

好的...再次编辑,现在使用WITH:

WiTH 
A0 AS (SELECT 0 as N FROM DUAL UNION ALL SELECT 0 FROM DUAL),
A1 AS (SELECT 0 as N FROM A0, A0 AS B),
A2 AS (SELECT 0 as N FROM A1, A1 AS B),
A3 AS (SELECT 0 as N FROM A2, A2 AS B),
A4 AS (SELECT 0 as N FROM A3, A3 AS B),
A5 AS (SELECT 0 as N FROM A4, A4 AS B),
A6 AS (SELECT 0 as N FROM A5, A5 AS B),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY N) AS Val FROM A6)
SELECT *
FROM Nums
WHERE Val <= :NUM
;

答案 2 :(得分:3)

我没有提出这个答案[所以确保任何选票都是正确的!!],它只是我的测试笔记基于'OMG小马'[谁不确定该方法是否适用于绑定变量]以上参考:

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> var num_rows number
SQL> begin select 20 into :num_rows from dual;
  2  end;
  3  /

PL/SQL procedure successfully completed.

SQL> select level from dual
  2  connect by level <=:num_rows;

     LEVEL
----------
         1
         2
         3
         4
 ...

答案 3 :(得分:2)

无连接查询

WITH num(n) as(select 1 from dual union all
select n+1 from num where n <= :num_limit)
select * from num

答案 4 :(得分:0)

我正在标记这个社区维基,因为它实际上并没有满足你对没有表的要求,但是我们在安装数据库时首先要做的就是为这种目的创建一组表。

  • 包含大量整数的表(例如,-99999到99999)。
  • 一张表格,其中包含过去10年至未来10年的所有日期(每月持续添加并偶尔修剪)。
  • 包含当天每小时的表格。

通过这样做,我们以(最小和最便宜的)磁盘空间为代价,大大降低了大量查询的复杂性并提高了速度。

你应该认真考虑一下。除了维护日期表外,还不需要很多维护。

答案 5 :(得分:0)

另一个解决方案需要一些PL / SQL来创建一个函数来返回带有行的集合......不像select level from dual connect by level <= :b1方法那么简单,但它在以下几种情况下很有用:

1)创建一个数字表对象类型(在本例中为number_tbl):

create or replace type number_tbl as table of number;

2)创建一个函数,它将接收要生成的行数,然后返回一个带有结果的number_tbl对象:

create or replace function get_rows( i_num_rows number ) return number_tbl as
  t number_tbl := number_tbl();
begin
  if i_num_rows < 1 then
    return null;
  end if;

  t.extend( i_num_rows );

  for i in 1..i_num_rows loop
    t(i) := i;
  end loop;

  return t;
end get_rows;

3)使用table( ... )函数从您的函数中选择将number_tbl对象转换为可选择的对象:

select * from table( cast ( get_rows( :b1 ) as number_tbl ) );

答案 6 :(得分:0)

连接是如此美妙的事情。它可以帮助您生成多行,并在双表中提供一组数据。这可以帮助您为虚拟数据生成大量行。例如

insert into test select a.* from test1 a,(select * from dual connect by level <=100000) b;

或者你可以做这样的事情

示例2:您希望打印1到10之间的方形和立方体数。

SQL> select level "No", power(level,2) "Square", power(level,3) "Cube"  from dual     connect by level <= 10;

    No     Square       Cube
---------- ---------- ----------
     1          1          1
     2          4          8
     3          9         27
     4         16         64
     5         25        125
     6         36        216
     7         49        343
     8         64        512
     9         81        729
    10        100       1000

因此,您可以以任何您想要的形式操纵它。这是您可以从双表中返回多行的方法。  参考文献:http://www.oraclebin.com/2012/12/multipe-rows-from-dual-table.html

答案 7 :(得分:0)

另一种方法是使用XQuery范围表达式,例如:

select column_value from xmltable(:a||' to '||:b);

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

此解决方案非常灵活,例如:

select column_value from xmltable('5 to 10, 15 to 20');

 5
 6
 7
 8
 9
10
15
16
17
18
19
20

答案 8 :(得分:0)

WITH cte_numbers(n) 
AS (
    SELECT 0
    UNION  ALL
    SELECT n + 1
    FROM  cte_numbers
    WHERE n < 10
)
SELECT n
FROM cte_numbers;

返回的行 0 1个 2 3 4 5 6 7 8 9 10

答案 9 :(得分:-1)

取决于数据库可以使用各种方法。

PostgreSQL有一个不错的功能 - series

获得你想要的东西:

SELECT * FROM generate_series(1, NUM);