programing

듀얼에서 N개의 행을 반환하는 SQL 쿼리

oldcodes 2023. 7. 18. 21:57
반응형

듀얼에서 N개의 행을 반환하는 SQL 쿼리

바인딩 변수(예::NUM)를 수락하는 SQL 쿼리를 작성하고 출력은 하나의 열과 각 행의 행 번호를 갖는 행 수로 구성됩니다. 즉, :NUM을 7로 전달하면 출력은 다음과 같아야 합니다.

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

쿼리에 실제 DB 테이블이 없어야 하며 PL/SQL 코드를 사용해서는 안 됩니다. 즉, 쿼리에는 dual만 사용해야 합니다.

이것을 달성할 수 있는 방법이 있습니까?

다음을 사용할 수 있습니다.

 WHERE ROWNUM <= :NUM

...그러나 테이블에는 바인딩 변수의 한계와 같거나 큰 행이 포함되어야 합니다.이 링크는 Oracle에서 다양한 행 번호 생성 기술을 보여줍니다.

사용.CONNECT BYOracle 10g+:

SELECT LEVEL
  FROM DUAL
CONNECT BY LEVEL <= :NUM

확인자monojohnny바인딩 변수를 사용할 수 있습니다.하지만 Oracle 9i에서 실행 시도CONNECT BY구문이 지원되므로 ORA-01436 오류가 발생합니다.

내가 100% 이해하지 못하는 유일한 것은 CONNECT BY가 바인딩 변수의 제한을 수락할지 여부입니다.

참조:

다음과 같은 방법을 사용해 보십시오.

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
;

저는 이 답을 생각해 내지 않았습니다. [따라서 투표가 올바른 방향으로 진행되는지 확인하세요!!]. 위의 '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
 ...

연결하지 않은 쿼리 사용자

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

제가 이 커뮤니티 위키를 표시하는 이유는 테이블이 없다는 귀하의 요구 사항에 실제로 부합하지 않기 때문입니다. 하지만 데이터베이스를 설치할 때 가장 먼저 하는 일 중 하나는 이러한 목적을 위한 테이블 집합을 만드는 것입니다.

  • 많은 정수(예: -999999 ~ 99999)를 포함하는 표입니다.
  • 과거 10년부터 미래 10년까지의 모든 날짜를 포함하는 표(매달에 지속적으로 추가되고 가끔 트리밍됨).
  • 하루의 각 시간을 포함하는 표입니다.

이렇게 함으로써, 우리는 (최소한의 저렴한) 디스크 공간을 희생하면서 많은 쿼리의 복잡성을 크게 줄이고 속도를 높입니다.

당신은 그것에 대해 진지하게 생각해 봐야 합니다.날짜표를 유지하는 것 외에, 많은 유지보수가 필요하지 않습니다.

다른 솔루션에서는 행이 포함된 컬렉션을 반환하는 함수를 생성하려면 일부 PL/SQL이 필요합니다.그렇게 간단하지는 않습니다.select level from dual connect by level <= :b1접근 방식은 다음과 같은 몇 가지 상황에서 유용합니다.

번호 테이블 개체 유형(이 예에서는 number_tbl)을 만듭니다.

create or replace type number_tbl as table of number;

생성할 행 수를 수신할 함수를 만든 다음 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;

선니합다택기서능을 합니다.table( ... )가능한 객체로 : number_tbl 객체택능한객변함수환하는체로가를:

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

커넥트 바이는 정말 멋진 것입니다.이를 통해 이중 테이블에서 사용할 수 있는 단일 데이터 집합으로 여러 행을 생성할 수 있습니다.이를 통해 더미 데이터에 대해 행 수를 크게 줄일 수 있습니다.예를들면

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

또 다른 방법은 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
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

데이터베이스에 따라 다양한 방법을 사용할 수 있습니다.

PostgreSQL에는 멋진 기능인 시리즈가 있습니다.

원하는 것을 얻기 위해:

SELECT * FROM generate_series(1, NUM);

언급URL : https://stackoverflow.com/questions/1973676/sql-query-to-return-n-rows-from-dual

반응형