programing

Oracle SQL:두 숫자 사이의 모든 정수 가져오기

lastmoon 2023. 6. 11. 11:14
반응형

Oracle SQL:두 숫자 사이의 모든 정수 가져오기

Oracle에서 SQL로 두 숫자 사이에 포함되는 숫자(정수)를 선택할 수 있는 방법이 있습니까? PL/SQL 프로시저나 함수를 만들고 싶지 않습니다.

예를 들어 3에서 10 사이의 숫자를 얻어야 합니다.결과 값은 3,4,5,6,7,8,9,10이 됩니다.

고마워.

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

새 데이터베이스를 작성할 때 가장 먼저 수행하는 작업은 일부 기본 테이블을 작성하고 채우는 것입니다.

하나는 -N과 N 사이의 모든 정수 목록이고, 다른 하나는 과거 5년에서 미래 10년 사이의 날짜 목록입니다(예약된 작업이 필요에 따라 계속 생성할 수 있음). 마지막은 하루 동안 모든 시간 목록입니다.예를 들어, 다음과 같이 입력합니다.

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 기반 DBMS에서 매우 휴대성이 뛰어납니다.

그러면 특정 쿼리가 단순해집니다.

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

시간 수치와 날짜 범위는 우리가 작업하는 보고 애플리케이션에 매우 유용합니다.이를 통해 실제 데이터가 없는 시간(또는 날짜)에 대해 0개의 항목을 생성할 수 있으므로 (월 둘째 날에 데이터가 없는 경우) 대신 다음과 같은 작업을 수행할 수 있습니다.

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
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.

이것은 토니의 것과 같은 속임수를 사용합니다.SQL*Plus 9를 사용하는 경우 Tony가 보여준 대로 이 쿼리를 인라인 뷰로 만들어야 합니다.SQL*Plus 10 이상에서는 위의 내용으로 충분합니다.

안녕, 롭.

이에 대해 MODEL 절을 사용할 수 있습니다.

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

이 한 줄 쿼리가 도움이 될 것입니다.

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

명확한 설명이 있으면 제게 알려주세요.

범위에서 숫자를 생성하는 한 가지 방법은 다음과 같습니다.XMLTABLE('start to end'):

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

COLUMN_VALUE가 문자열이기 때문에 TO_NUMBER에 추가했습니다.

DB Fidle 데모

또는 Between을 사용할 수 있습니다.

Select Column1 from dummy_table where Column2 Between 3 and 10

Gary, 그가 설명한 결과를 보여주기 위해 모델 쿼리는 다음과 같습니다.

듀얼 모델 치수에서 c1 선택(1 asrn)
측정(1 as c1) 규칙 반복(8)(c1[ITERATION_NUMBER]=DICOM_NUMBER+3) 순서 변경

;)

항상 사용하는 항목:

레벨 <= 8을 기준으로 이중 연결의 결과로 선택(레벨 - 1) + 3

여기서 3은 시작 번호이고 8은 "반복"의 수입니다.

이것은 늦게 추가된 것입니다.하지만 솔루션이 더 우아하고 사용하기 쉬운 것 같습니다.

한 번 설치해야 하는 파이프라인 기능을 사용합니다.

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에 따라 다릅니다.

SQL Server에서 테이블 값 함수를 사용하여 이 작업을 수행했습니다. 관심 있는 사람이 있다면 완벽하게 작동합니다.

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

쿼리를 실행하는 경우: "dbo에서 *를 선택합니다.사이의 숫자(1,5)"(물론 인용문 없음) 결과는

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

쉼표 문자열과 '-'로 구분된 숫자 목록을 동등한 확장된 숫자 목록으로 변환하는 유용한 쿼리를 공유하려고 합니다.

'1,2,3,50-60'을 다음으로 변환하는 예제

1235051...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' 문자열을 매개 변수화할 수 있습니다.

create table numbers (value number);

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

이미 제공된 답변 외에도 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

언급URL : https://stackoverflow.com/questions/1453747/oracle-sqlget-all-integers-between-two-numbers

반응형