2010-05-17 30 views
35

Wie kann ich mit der Tabelle DUAL eine Liste von Zahlen von 1 bis 100 erhalten?SQL zum Generieren einer Liste von Zahlen von 1 bis 100

+0

Ist das Hausaufgaben? Wenn nicht, erscheint die enthaltene Anforderung, "die DUAL-Tabelle zu verwenden", willkürlich und seltsam für mich. – bart

+4

@bart - die Verwendung von DUAL als Quelle ist eine bekannte Lösung für das Problem der Generierung von Zeilen, so dass ihre Einbeziehung in die Frage weder willkürlich noch merkwürdig ist. – APC

+0

wäre es interessant zu wissen, warum Sie das tun wollen. – Randy

Antwort

53

Ihre Frage ist schwer zu verstehen, aber wenn man die Zahlen 1-100 auswählen möchten, dann sollte dies den Trick:

Select Rownum r 
From dual 
Connect By Rownum <= 100 
6

Peter Antwort ist mein Favorit, auch.

Wenn Sie nach mehr Details suchen, gibt es einen ziemlich guten Überblick, IMO, here. Besonders interessant ist es, die benchmarks zu lesen.

+0

Danke - dein erster Link war sehr nützlich. – Juffy

19

Eine weitere interessante Lösung in ORACLE PL/SQL:

SELECT LEVEL n 
     FROM DUAL 
CONNECT BY LEVEL <= 100; 
+7

Das ist einfach Oracle SQL. Es funktioniert gut außerhalb eines PL/SQL-Kontexts. –

12

es auf die harte Art und Weise tun. Verwenden Sie die ehrfürchtige MODEL Klausel:

SELECT V 
FROM DUAL 
MODEL DIMENSION BY (0 R) 
     MEASURES (0 V) 
     RULES ITERATE (100) (
     V[ITERATION_NUMBER] = ITERATION_NUMBER + 1 
    ) 
ORDER BY 1 

Beweis: http://sqlfiddle.com/#!4/d41d8/20837

+2

das ist einfach, warum nicht Muster übereinstimmen ... :-) – igr

+2

@igr: Ich fordere Sie heraus, diese Antwort tatsächlich zu liefern :-) –

+0

was 'CV (R)' bedeutet? Ist es wie aktueller Wert? oder etw? – zygimantus

0

Eine Variante von Peters Beispiel, die eine Art und Weise zeigt diese verwendet werden könnten, alle Zahlen zwischen 0 und 99.

with digits as (
    select mod(rownum,10) as num 
    from dual 
    connect by rownum <= 10 
) 
select a.num*10+b.num as num 
from digits a 
     ,digits b 
order by num 
; 

zu erzeugen So etwas wird nützlich, wenn Sie die Zuweisung von Stapelbezeichnern durchführen und nach Elementen suchen, die noch nicht zugewiesen wurden.

Zum Beispiel, wenn Sie Bingo-Tickets verkaufen, möchten Sie möglicherweise Losen von 100 Stock Personal zuordnen (raten Sie, wie ich früher für den Sport erhöht zu finanzieren). Wenn sie eine Charge verkaufen, erhalten sie die nächste Charge der Reihe nach. Jedoch können Leute, die die Tickets kaufen, auswählen, irgendwelche Tickets aus dem Stapel zu kaufen. Die Frage könnte sein, "welche Tickets verkauft worden sind".

In diesem Fall haben wir nur eine unvollständige, zufällige Liste von Tickets, die innerhalb des angegebenen Stapels zurückgegeben wurden, und benötigen eine vollständige Liste aller Möglichkeiten, um festzustellen, was wir nicht haben.

with range as (
    select mod(rownum,100) as num 
    from dual 
    connect by rownum <= 100 
), 
AllPossible as (
    select a.num*100+b.num as TicketNum 
    from batches a 
     ,range b 
    order by num 
) 
select TicketNum as TicketsSold 
from AllPossible 
where AllPossible.Ticket not in (select TicketNum from TicketsReturned) 
; 

Excuse die Verwendung von Schlüsselwörtern, änderte ich einige Variablennamen aus einer realen Welt Beispiel.

... Um zu zeigen, warum so etwas wie dies nützlich wäre

-1
SELECT * FROM `DUAL` WHERE id>0 AND id<101 

Die obige Abfrage in SQL in der Datenbank geschrieben werden.

+0

Für welche Datenbank ist das gedacht? –

5

Wenn Sie möchten, dass Ihre Ganzzahlen zwischen zwei Ganzzahlen gebunden sind (z.mit etwas anderem als 1) starten, können Sie so etwas wie dieses verwenden:

with bnd as (select 4 lo, 9 hi from dual) 
select (select lo from bnd) - 1 + level r 
from dual 
connect by level <= (select hi-lo from bnd); 

Es gibt:

4 
5 
6 
7 
8 
0

Ich habe eine Oracle-Funktion, die gibt eine Tabelle von Zahlen

CREATE OR REPLACE FUNCTION [schema].FN_TABLE_NUMBERS(
    NUMINI INTEGER, 
    NUMFIN INTEGER, 
    EXPONENCIAL INTEGER DEFAULT 0 
) RETURN TBL_NUMBERS 
IS 
    NUMEROS TBL_NUMBERS; 
    INDICE NUMBER; 
BEGIN 
    NUMEROS := TBL_NUMBERS(); 

    FOR I IN (
     WITH TABLA AS (SELECT NUMINI, NUMFIN FROM DUAL) 
     SELECT NUMINI NUM FROM TABLA UNION ALL 
     SELECT 
      (SELECT NUMINI FROM TABLA) + (LEVEL*TO_NUMBER('1E'||TO_CHAR(EXPONENCIAL))) NUM 
     FROM DUAL 
     CONNECT BY 
      (LEVEL*TO_NUMBER('1E'||TO_CHAR(EXPONENCIAL))) <= (SELECT NUMFIN-NUMINI FROM TABLA) 
    ) LOOP 
     NUMEROS.EXTEND; 
     INDICE := NUMEROS.COUNT; 
     NUMEROS(INDICE):= i.NUM; 
    END LOOP; 

    RETURN NUMEROS; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
     RETURN NUMEROS; 
    WHEN OTHERS THEN 
     RETURN NUMEROS; 
END; 
/

Ist erforderlich, erstellen Sie einen neuen Datentyp:

CREATE OR REPLACE TYPE [schema]."TBL_NUMBERS" IS TABLE OF NUMBER; 
/

Verbrauch:

SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10))--integers difference: 1;2;.......;10 

Und wenn Sie Dezimalzahlen zwischen den Zahlen von Exponencial Notation müssen:

SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10,-1));--with 0.1 difference: 1;1.1;1.2;.......;10 
SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10,-2));--with 0.01 difference: 1;1.01;1.02;.......;10 
2

Mit GROUP BY CUBE:

SELECT ROWNUM 
FROM (SELECT 1 AS c FROM dual GROUP BY CUBE(1,1,1,1,1,1,1)) sub 
WHERE ROWNUM <=100; 

Rextester Demo

-1

Nein n eed zu bekommen alle klug für schlappe 100 Zahlen, nur rohe Gewalt es;)

select 1 from dual union 
select 2 from dual union 
select 3 from dual union 
select 4 from dual union 
select 5 from dual union 
select 6 from dual union 
select 7 from dual union 
select 8 from dual union 
select 9 from dual union 
select 10 from dual union 
select 11 from dual union 
select 12 from dual union 
select 13 from dual union 
select 14 from dual union 
select 15 from dual union 
select 16 from dual union 
select 17 from dual union 
select 18 from dual union 
select 19 from dual union 
select 20 from dual union 
select 21 from dual union 
select 22 from dual union 
select 23 from dual union 
select 24 from dual union 
select 25 from dual union 
select 26 from dual union 
select 27 from dual union 
select 28 from dual union 
select 29 from dual union 
select 30 from dual union 
select 31 from dual union 
select 32 from dual union 
select 33 from dual union 
select 34 from dual union 
select 35 from dual union 
select 36 from dual union 
select 37 from dual union 
select 38 from dual union 
select 39 from dual union 
select 40 from dual union 
select 41 from dual union 
select 42 from dual union 
select 43 from dual union 
select 44 from dual union 
select 45 from dual union 
select 46 from dual union 
select 47 from dual union 
select 48 from dual union 
select 49 from dual union 
select 50 from dual union 
select 51 from dual union 
select 52 from dual union 
select 53 from dual union 
select 54 from dual union 
select 55 from dual union 
select 56 from dual union 
select 57 from dual union 
select 58 from dual union 
select 59 from dual union 
select 60 from dual union 
select 61 from dual union 
select 62 from dual union 
select 63 from dual union 
select 64 from dual union 
select 65 from dual union 
select 66 from dual union 
select 67 from dual union 
select 68 from dual union 
select 69 from dual union 
select 70 from dual union 
select 71 from dual union 
select 72 from dual union 
select 73 from dual union 
select 74 from dual union 
select 75 from dual union 
select 76 from dual union 
select 77 from dual union 
select 78 from dual union 
select 79 from dual union 
select 80 from dual union 
select 81 from dual union 
select 82 from dual union 
select 83 from dual union 
select 84 from dual union 
select 85 from dual union 
select 86 from dual union 
select 87 from dual union 
select 88 from dual union 
select 89 from dual union 
select 90 from dual union 
select 91 from dual union 
select 92 from dual union 
select 93 from dual union 
select 94 from dual union 
select 95 from dual union 
select 96 from dual union 
select 97 from dual union 
select 98 from dual union 
select 99 from dual union 
select 100 from dual; 
0

Hier ist eine unterhaltsame Art und Weise ist eine Wertetabelle zu generieren. Es wird nicht die DUAL-Tabelle verwendet, aber sollte die DUAL-Tabelle jemals verschwinden, könnte dies ein Backup-Plan sein.

DECLARE @TotalNumbers INT = 100; 

DECLARE @From DATETIME = CONVERT(DATETIME, CONVERT(DATE, GETDATE())), 
     @To DATETIME = DATEADD(SECOND, @TotalNumbers - 1, CONVERT(DATETIME, CONVERT(DATE, GETDATE()))); 

WITH AlmostNumberTable (Hola) 
AS (SELECT @From 
    UNION ALL 
    SELECT DATEADD(SECOND, 1, Hola) 
    FROM AlmostNumberTable 
    WHERE Hola< @To 
    ) 
SELECT [Number] 
FROM 
(
    SELECT DATEPART(MINUTE, AlmostNumberTable.Hola) * 60 + DATEPART(SECOND, AlmostNumberTable.Hola) + 1 AS [Number] 
    FROM AlmostNumberTable 
) AS NumberTable; 

Es ist wahrscheinlich Unsinn, aber es ist eine funktionierende Lösung und es hat Spaß gemacht zu schreiben.

Verwandte Themen