Używając tabeli DUAL, jak mogę uzyskać listę liczb od 1 do 100?SQL do generowania listy liczb od 1 do 100
Odpowiedz
Twoje pytanie jest trudne do zrozumienia, ale jeśli chcesz, aby wybrać numery od 1
do 100
, to powinno załatwić sprawę:
Select Rownum r
From dual
Connect By Rownum <= 100
odpowiedź Piotra jest moim ulubionym, zbyt.
Jeśli szukasz więcej szczegółów, istnieje niezły przegląd, IMO, here. Szczególnie interesujące jest odczytanie benchmarks.
Dzięki - twój pierwszy link był bardzo przydatny. – Juffy
Innym ciekawym rozwiązaniem w Oracle PL/SQL:
SELECT LEVEL n
FROM DUAL
CONNECT BY LEVEL <= 100;
To jest zwykły Oracle SQL. Działa dobrze poza kontekstem PL/SQL. –
zrobić to w przykry sposób. Użyj niesamowite MODEL
klauzuli:
SELECT V
FROM DUAL
MODEL DIMENSION BY (0 R)
MEASURES (0 V)
RULES ITERATE (100) (
V[ITERATION_NUMBER] = ITERATION_NUMBER + 1
)
ORDER BY 1
To proste, dlaczego nie pasuje do wzoru ... :-) – igr
@igr: Rzucam Ci wyzwanie, abyś faktycznie udzielił tej odpowiedzi :-) –
co to jest "CV (R)"? Czy to jest jak aktualna wartość? czy coś? – zygimantus
Wariant przykładu Piotra, który pokazuje sposób ten może być wykorzystywany do generowania wszystkie liczby z zakresu od 0 do 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
;
Coś takiego przydaje się, gdy wykonujesz przypisanie identyfikatorów partii i szukasz przedmiotów, które nie zostały jeszcze przypisane.
Na przykład, jeśli sprzedajesz bilety do gry w bingo, możesz chcieć przydzielić partie 100 pracowników piętra (zgadnij, w jaki sposób użyłem do finansowania podwyżki na sport). Gdy sprzedają partię, otrzymują kolejną partię w sekwencji. Jednak osoby kupujące bilety mogą wybrać zakup biletów z partii. Można zadać pytanie: "jakie bilety zostały sprzedane".
W tym przypadku mamy tylko częściową, losową, listę biletów, które zostały zwrócone w ramach danej partii i wymagają pełnej listy wszystkich możliwości ustalenia, których nie mamy.
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)
;
Przepraszam za użycie słów kluczowych, zmieniłem niektóre nazwy zmiennych z przykładu z prawdziwego świata.
... Aby wykazać, dlaczego coś takiego byłoby przydatne
SELECT * FROM `DUAL` WHERE id>0 AND id<101
Powyższe zapytanie jest napisane w SQL w bazie danych.
Do której bazy danych to służy? –
Jeśli chcesz, aby liczby całkowite były powiązane między dwiema liczbami całkowitymi (np.zacząć od czegoś innego niż 1), można użyć mniej więcej tak:
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);
Daje:
4
5
6
7
8
stworzyłem funkcję Oracle, która zwraca tablicę liczb
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;
/
Konieczne jest utworzenie nowego typu danych:
CREATE OR REPLACE TYPE [schema]."TBL_NUMBERS" IS TABLE OF NUMBER;
/
Zastosowanie:
SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10))--integers difference: 1;2;.......;10
A jeśli potrzebujesz dziesiętnych pomiędzy liczbami autorem exponencial notacji:
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
Korzystanie 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;
nr n Potrzeba, aby dostać wszystko mądry dla measly 100 numerów, po prostu brute force go;)
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;
Oto świetny sposób, aby wygenerować tabelę numeryczny. Nie używa tabeli DUAL, ale jeśli tabela DUAL kiedykolwiek zniknie, może to być plan zapasowy.
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;
To chyba bzdura, ale to działające rozwiązanie i fajnie było pisać.
Czy to zadanie domowe? Jeśli nie, uwzględniony wymóg "używania tabeli DUAL" wydaje mi się arbitralny i dziwny. – bart
@bart - używanie DUAL jako źródła jest dobrze znanym rozwiązaniem problemu generowania wierszy, więc jego włączenie do pytania nie jest ani arbitralne, ani dziwne. – APC
byłoby interesujące wiedzieć, dlaczego chcesz to zrobić. – Randy