web-dev-qa-db-fra.com

SQL pour générer une liste de nombres de 1 à 100

À l'aide du tableau DUAL, comment puis-je obtenir une liste de nombres de 1 à 100?

40
ramachandrareddy

Votre question est difficile à comprendre, mais si vous voulez sélectionner les nombres de 1 à 100, alors cela devrait faire l'affaire:

Select Rownum r
From dual
Connect By Rownum <= 100
67
Peter Lang

Une autre solution intéressante dans Oracle PL/SQL:

    SELECT LEVEL n
      FROM DUAL
CONNECT BY LEVEL <= 100;
22
UltraCommit

Faites-le à la dure. Utilisez la clause awesome MODEL:

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

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

12
Lukas Eder

La réponse de Peter est aussi ma préférée.

Si vous recherchez plus de détails, il y a un assez bon aperçu, IMO, here .
Il est particulièrement intéressant de lire les points de repère .

7
Unreason

Si vous voulez que vos entiers soient liés entre deux entiers (c'est-à-dire, commencez par autre chose que 1), vous pouvez utiliser quelque chose comme ça:

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

Il donne:

4
5
6
7
8
5
vadipp

À l'aide de la clause de sous-fabrique de requête d'Oracle "WITH", vous pouvez sélectionner des nombres de 1 à 100:

WITH t(n) AS (
  SELECT 1 from dual
  UNION ALL
    SELECT n+1 FROM t WHERE n < 100
)
SELECT * FROM t;
2
echo

Vous pouvez utiliser XMLTABLE:

SELECT rownum
FROM XMLTABLE('1 to 100');

DBFiddle Demo

2
Lukasz Szozda

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

Démonstration de Rextester

1
Lukasz Szozda

Voici un moyen amusant de générer une table numérique. Il n'utilise pas la table DUAL, mais si la table DUAL devait disparaître, il pourrait s'agir d'un plan de secours.

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;

C'est probablement un non-sens, mais c'est une solution qui fonctionne et c'était amusant d'écrire.

0

Une variante de l'exemple de Peter, qui montre comment l'utiliser pour générer tous les nombres compris entre 0 et 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
;

Cela devient utile lorsque vous effectuez une affectation d'identificateur de lot et que vous recherchez les éléments qui n'ont pas encore été attribués.

Par exemple, si vous vendez des billets de bingo, vous pouvez attribuer des lots de 100 personnes au sol (devinez comment je collectais des fonds pour le sport). Comme ils vendent un lot, ils reçoivent le prochain lot en séquence. Toutefois, les personnes qui achètent les billets peuvent choisir d'acheter n'importe quel billet du lot. La question peut être posée, "quels billets ont été vendus". 

Dans ce cas, nous ne disposons que d’une liste partielle et aléatoire des tickets qui ont été renvoyés dans le même lot, et nous avons besoin d’une liste complète de toutes les possibilités pour déterminer ce que nous n’avons pas.

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

Excusez l'utilisation de mots-clés, j'ai changé certains noms de variables à partir d'un exemple réel.

... Pour démontrer pourquoi quelque chose comme cela serait utile

0
Jefferey Cave

J'ai créé une fonction Oracle qui renvoie une table de nombres

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

Est nécessaire créer un nouveau type de données:

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

Usage:

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

Et si vous avez besoin de nombres décimaux entre nombres par notation exponenciale:

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
0
Joaquinglezsantos