wake-up-neo.com

ORACLE SQL: Hole alle Zahlen zwischen zwei Zahlen

Gibt es eine Möglichkeit, die Zahlen (Ganzzahlen) auszuwählen, die zwischen zwei Zahlen mit SQL in Oracle enthalten sind; Ich möchte keine PL/SQL-Prozedur oder -Funktion erstellen. 

Zum Beispiel brauche ich die Zahlen zwischen 3 und 10. Das Ergebnis sind die Werte 3,4,5,6,7,8,9,10. 

Vielen Dank. 

20
George

Dieser Trick mit der DUAL-Tabelle von Oracle funktioniert auch:

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
51
Tony Andrews

Dasfirst, was ich beim Erstellen einer neuen Datenbank mache, ist das Erstellen und Auffüllen einiger grundlegender Tabellen.

Eine ist eine Liste aller Ganzzahlen zwischen -N und N, eine andere ist eine Liste von Daten, die 5 Jahre in der Vergangenheit und 10 Jahre in der Zukunft liegen (ein geplanter Job kann diese nach Bedarf und in Zukunft erstellen), und die letzte ist eine Liste aller Stunden den ganzen Tag. Zum Beispiel die Inetger:

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;

Dies gilt für DB2/z, das über einen automatischen Start der Transaktion verfügt, weshalb nackte Commits angezeigt werden.

Ja, es nimmt einen (minimalen) Platz ein, aber es macht das Schreiben von Abfragenmucheinfacher, indem einfach Werte aus diesen Tabellen ausgewählt werden. Es ist auch sehr portabel fürjedesSQL-basierte DBMS.

Ihre spezielle Frage wäre dann eine einfache:

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

Die Stundenzahlen und Datumsbereiche sind für die Berichtsanwendungen, an denen wir arbeiten, sehr nützlich. Es erlaubt uns, Null Einträge für die Stunden des Tages (oder Daten) zu erstellen, die keine echten Daten haben, so dass anstelle von (wo es keine Daten für die Sekunde des Monats gibt):

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

wir können stattdessen bekommen:

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

Sie können dazu die MODEL-Klausel verwenden.

SELECT c1 from dual
  MODEL DIMENSION BY (1 as rn)  MEASURES (1 as c1)
  RULES ITERATE (7)
  (c1[ITERATION_NUMBER]=ITERATION_NUMBER+7)
4
Gary Myers
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.

Dies verwendet den gleichen Trick wie Tony. Beachten Sie, dass Sie bei der Verwendung von SQL * Plus 9 diese Abfrage zu einer Inline-Ansicht machen müssen, wie Tony Ihnen gezeigt hat. In SQL * Plus 10 oder höher reicht das oben aus.

Grüße, Rob.

4
Rob van Wijk

diese einzeilige Abfrage wird Ihnen helfen,

select level lvl from dual where level<:upperbound and 

                              level >:lowerbound connect by level<:limt

Für Ihren Fall:

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

lassen Sie mich wissen, wenn Sie eine Klarstellung haben.

2
Thiyagu ATR

Oder du kannst Zwischen verwenden

Select Column1 from dummy_table where Column2 Between 3 and 10
1
Amit

Eine Möglichkeit, Zahlen aus dem Bereich zu generieren, ist XMLTABLE('start to end'):

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

DBFiddle Demo

1
Lukasz Szozda

Dies ist eine späte Ergänzung. Die Lösung scheint jedoch eleganter und benutzerfreundlicher zu sein.

Es verwendet eine Pipeline-Funktion, die einmal installiert werden muss:

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;
/

Dann kannst du es so benutzen:

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

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

Die Lösung ist Oracle-spezifisch.

1
Codo

Gary, um das Ergebnis zu zeigen, das er erklärt hat, lautet die Modellabfrage:

SELECT c1 FROM DUAL MODEL DIMENSION BY (1 wie rn)
MASSNAHMEN (1 wie c1) REGELN ITERATE (8) (C1 [ITERATION_NUMBER] = ITERATION_NUMBER + 3) ORDER BY RN

;) 

Ich verwende immer: 

SELECT (LEVEL - 1) + 3 als Ergebnis FROM Dual CONNECT BY Level <= 8

Dabei ist 3 die Startnummer und 8 die Anzahl der "Iterationen". 

1
anthian

Ich habe nur eine Tabellenwertfunktion ausgeführt, um dies auf dem SQL-Server auszuführen. Wenn jemand interessiert ist, funktioniert dies einwandfrei.

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

Wenn Sie die Abfrage ausführen: "select * from dbo.NumbersBetween (1,5)" (natürlich ohne Anführungszeichen), wird das Ergebnis angezeigt

Number
-------
1
2
3
4
5
0
Gaspa79

Ich möchte eine nützliche Abfrage freigeben, die eine durch Kommas und '-' getrennte Liste von Zahlen in eine entsprechende erweiterte Liste von Zahlen konvertiert:

Ein Beispiel, das '1,2,3,50-60' in konvertiert 

 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;

Sie können es als Ansicht verwenden und die Zeichenfolge '1,2,3,50-60' parametrisieren

0
antoniolvsa
create table numbers (value number);

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