Method #1: Use a table that already has enough rows
with blist (nr, letter)
as (select rownum rn, chr( rownum + ascii('A') - 1)
from all_objects
where ascii('Z')-ascii('A')+1 >= rownum
)
select * from blist
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #2: use union all (hardcoding values)
With blist (Nr)
as (select 65 From Dual UNION ALL
select 66 From Dual UNION ALL
select 67 From Dual UNION ALL
select 68 From Dual UNION ALL
select 69 From Dual UNION ALL
select 70 From Dual UNION ALL
select 71 From Dual UNION ALL
select 72 From Dual UNION ALL
select 73 From Dual UNION ALL
select 74 From Dual UNION ALL
select 75 From Dual UNION ALL
select 76 From Dual UNION ALL
select 77 From Dual UNION ALL
select 78 From Dual UNION ALL
select 79 From Dual UNION ALL
select 80 From Dual UNION ALL
select 81 From Dual UNION ALL
select 82 From Dual UNION ALL
select 83 From Dual UNION ALL
select 84 From Dual UNION ALL
select 85 From Dual UNION ALL
select 86 From Dual UNION ALL
select 87 From Dual UNION ALL
select 88 From Dual UNION ALL
select 89 From Dual UNION ALL
select 90 From Dual)
Select Nr, chr(Nr) as letter
From blist
NR | LETTER | 65 | A | 66 | B | 67 | C | 68 | D | 69 | E | 70 | F | 71 | G | 72 | H | 73 | I | 74 | J | 75 | K | 76 | L | 77 | M | 78 | N | 79 | O | 80 | P | 81 | Q | 82 | R | 83 | S | 84 | T | 85 | U | 86 | V | 87 | W | 88 | X | 89 | Y | 90 | Z |
---|
Method #3: hierarchical query with CONNECT BY
With blist ( Nr, letter)
as (select level, chr(level+ascii('A')-1)
from dual
CONNECT BY LEVEL<= ascii('Z')-ascii('A')+1
)
Select * from blist
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #4: hierarchical query with WITH
With blist ( Nr, letter)
as (select ascii('A'), 'A' from dual
UNION ALL
select b.nr+1, chr(b.nr+1)
from blist b
where chr(b.nr+1) <= 'Z'
)
Select * from blist
NR | LETTER | 65 | A | 66 | B | 67 | C | 68 | D | 69 | E | 70 | F | 71 | G | 72 | H | 73 | I | 74 | J | 75 | K | 76 | L | 77 | M | 78 | N | 79 | O | 80 | P | 81 | Q | 82 | R | 83 | S | 84 | T | 85 | U | 86 | V | 87 | W | 88 | X | 89 | Y | 90 | Z |
---|
Method #5.1: cartesian product by CROSS JOIN
with ten (nr) as (select level-1 nr from dual connect by level <= 10)
,hundred (nr) as (select t1.nr+ 10*t2.nr from ten t1 CROSS JOIN ten t2)
,blist(nr, letter) as (select nr, chr(nr+ascii('A')) from hundred where chr(nr+ascii('A'))<= 'Z')
select *
from blist
order by nr
NR | LETTER | 0 | A | 1 | B | 2 | C | 3 | D | 4 | E | 5 | F | 6 | G | 7 | H | 8 | I | 9 | J | 10 | K | 11 | L | 12 | M | 13 | N | 14 | O | 15 | P | 16 | Q | 17 | R | 18 | S | 19 | T | 20 | U | 21 | V | 22 | W | 23 | X | 24 | Y | 25 | Z |
---|
Method #5.2: cartesian product by normal JOINs
with ten (nr) as (select 1 nr from dual connect by level <= 10)
,hundred (nr) as (select rownum from ten t1 JOIN ten t2 on t1.nr=t2.nr)
,blist(nr, letter) as (select nr, chr(nr+ascii('A')-1) from hundred where chr(nr+ascii('A')-1)<= 'Z')
select *
from blist
order by nr
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #6: group by CUBE to generate dummy rows
with
five (nr1, nr2, nr3, nr4, nr5)
as (select 1,1,1,1,1 from dual )
,cubelist (nr1, nr2, nr3, nr4, nr5)
as (select * from five GROUP BY CUBE(nr1,nr2,nr3,nr4,nr5) )
,blist (rn, letter)
as (select rownum, chr(rownum + ascii('A') - 1) as letter
from cubelist
where chr(rownum + ascii('A') - 1) <= 'Z')
select * from blist
RN | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #7.1: ITERATIVE MODEL using an absolute formula
with blist (nr, letter)
as (
select nr, letter from dual
MODEL
DIMENSION BY (1 nr)
MEASURES ('A' letter)
RULES iterate (100) until (letter[iteration_number] >= 'Z')
(
letter[iteration_number] = chr(ascii('A') + iteration_number) --absolute formula
)
)
select b.nr,b.letter
from blist b
order by b.nr,b.letter
NR | LETTER | 0 | A | 1 | B | 2 | C | 3 | D | 4 | E | 5 | F | 6 | G | 7 | H | 8 | I | 9 | J | 10 | K | 11 | L | 12 | M | 13 | N | 14 | O | 15 | P | 16 | Q | 17 | R | 18 | S | 19 | T | 20 | U | 21 | V | 22 | W | 23 | X | 24 | Y | 25 | Z |
---|
Method #7.2: ITERATIVE MODEL using a relative formula
with blist (nr, letter)
as (
select nr, letter from dual
MODEL
DIMENSION BY (1 nr) -- dummy value
MEASURES ('A' letter) -- dummy value
RULES iterate (100) until (letter[iteration_number] >= 'Z')
(
letter[iteration_number] = nvl(chr(ascii(letter[iteration_number-1]) + 1),'A') --relative formula
)
)
select b.nr,b.letter
from blist b
order by b.nr,b.letter
NR | LETTER | 0 | A | 1 | B | 2 | C | 3 | D | 4 | E | 5 | F | 6 | G | 7 | H | 8 | I | 9 | J | 10 | K | 11 | L | 12 | M | 13 | N | 14 | O | 15 | P | 16 | Q | 17 | R | 18 | S | 19 | T | 20 | U | 21 | V | 22 | W | 23 | X | 24 | Y | 25 | Z |
---|
Method #7.3: ITERATIVE MODEL using a relative formula with CV reference
with blist (nr, letter)
as (
select nr, letter from dual
MODEL
DIMENSION BY (1 nr)
MEASURES (' ' letter) --dummy value, will be overwritten later
RULES iterate (100) until (letter[iteration_number] >= 'Z') -- stop criteria
(
letter[-1] = 'A' -- Set start value to a dimension nr=-1 (before iteration starts)
,letter[iteration_number] = chr(ascii(letter[CV()-1])+1) --iterative formula using cell value function cv on right side
)
)
select b.nr, b.letter
from blist b
order by b.nr,b.letter
NR | LETTER | -1 | A | 0 | B | 1 | C | 2 | D | 3 | E | 4 | F | 5 | G | 6 | H | 7 | I | 8 | J | 9 | K | 10 | L | 11 | M | 12 | N | 13 | O | 14 | P | 15 | Q | 16 | R | 17 | S | 18 | T | 19 | U | 20 | V | 21 | W | 22 | X | 23 | Y | 24 | Z |
---|
Method #7.4: ITERATIVE MODEL using a starting dimension = -1
with blist (nr, letter)
as (
select nr, letter from dual
MODEL
DIMENSION BY (-1 nr)
MEASURES ('A' letter) -- Start value! Will not be overwritten anymore
RULES iterate (100) until (letter[iteration_number] >= 'Z') -- stop criteria
(
letter[iteration_number] = chr(ascii(letter[iteration_number-1])+1) --iterative formula using iteration_number also on right side
)
)
select b.nr, b.letter
from blist b
order by b.nr,b.letter
NR | LETTER | -1 | A | 0 | B | 1 | C | 2 | D | 3 | E | 4 | F | 5 | G | 6 | H | 7 | I | 8 | J | 9 | K | 10 | L | 11 | M | 12 | N | 13 | O | 14 | P | 15 | Q | 16 | R | 17 | S | 18 | T | 19 | U | 20 | V | 21 | W | 22 | X | 23 | Y | 24 | Z |
---|
Method #8: UPSERT MODEL using a FOR LOOP dimension rule
with blist (nr, letter)
as (select nr, letter from dual
MODEL
dimension by (ascii('A') nr)
MEASURES ('?' letter)
RULES UPSERT
(
letter[FOR nr from ascii('A') to ascii('Z') increment 1] = chr(cv(nr))
)
)
select b.nr, b.letter
from blist b
order by b.nr, b.letter
NR | LETTER | 65 | A | 66 | B | 67 | C | 68 | D | 69 | E | 70 | F | 71 | G | 72 | H | 73 | I | 74 | J | 75 | K | 76 | L | 77 | M | 78 | N | 79 | O | 80 | P | 81 | Q | 82 | R | 83 | S | 84 | T | 85 | U | 86 | V | 87 | W | 88 | X | 89 | Y | 90 | Z |
---|
Method #9.0: use a pipelined table function (PTF)
create or replace package swe_datatools
as
-- create a list of integers starting with 1
FUNCTION generate_series (nr_of_rows IN PLS_INTEGER) RETURN sys.ODCINUMBERLIST PIPELINED;
-- create a list of integers in a specified range
FUNCTION generate_series (nr_from IN PLS_INTEGER, nr_to IN PLS_INTEGER) RETURN sys.ODCINUMBERLIST PIPELINED;
-- create a list of (ascii)characters in a specified range
FUNCTION generate_series (letter_from IN varchar2, letter_to IN varchar2) RETURN sys.ODCIVARCHAR2LIST PIPELINED;
end swe_datatools;
Package created.
Method #9.0: use a pipelined table function (PTF)
create or replace package body swe_datatools
as
FUNCTION generate_series (nr_of_rows IN PLS_INTEGER) RETURN sys.ODCINUMBERLIST PIPELINED IS
BEGIN
FOR i IN 1 .. nr_of_rows LOOP
PIPE ROW (i);
END LOOP;
RETURN;
END generate_series;
FUNCTION generate_series (nr_from IN PLS_INTEGER, nr_to IN PLS_INTEGER) RETURN sys.ODCINUMBERLIST PIPELINED is
BEGIN
FOR i IN nr_from .. nr_to LOOP
PIPE ROW (i);
END LOOP;
RETURN;
END generate_series;
FUNCTION generate_series (letter_from IN varchar2, letter_to IN varchar2) RETURN sys.ODCIVARCHAR2LIST PIPELINED is
letter varchar(1);
BEGIN
if letter_from <= letter_to then
FOR i IN ascii(letter_from) .. ascii(letter_to) LOOP
PIPE ROW (chr(i));
END LOOP;
end if;
RETURN;
END generate_series;
end swe_datatools;
Package Body created.
Method #9.1: use a PTF to generate a list
with blist (letter)
as (select column_value from table(swe_datatools.generate_series('A','Z')))
select * from blist
LETTER | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
---|
Method #10.1: XMLTABLE with a simple range
with blist (nr, letter)
as (select column_value, chr(to_number(column_value) + ascii('A') - 1)
from XMLTABLE('1 to 50')
where chr(to_number(column_value) + ascii('A') - 1) <= 'Z'
)
select * from Blist
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #10.2: XMLTABLE with an int column
with blist (nr, letter)
as (select i, chr(to_number(i) + ascii('A') - 1)
from XMLTABLE('1 to 50' columns i int path '.')
where chr(to_number(i) + ascii('A') - 1) <= 'Z'
)
select * from blist
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #10.3: XMLTABLE using FOR ORDINALITY
with blist (nr, letter)
as (select i, chr(to_number(i) + ascii('A') - 1)
from XMLTABLE('1 to 50' columns i for ordinality)
where chr(to_number(i) + ascii('A') - 1) <= 'Z'
)
select * from blist
NR | LETTER | 1 | A | 2 | B | 3 | C | 4 | D | 5 | E | 6 | F | 7 | G | 8 | H | 9 | I | 10 | J | 11 | K | 12 | L | 13 | M | 14 | N | 15 | O | 16 | P | 17 | Q | 18 | R | 19 | S | 20 | T | 21 | U | 22 | V | 23 | W | 24 | X | 25 | Y | 26 | Z |
---|
Method #11: XML FLOWR solution
with blist (nr, letter)
as (select /*+ no_xml_query_rewrite */
x.val as nr,
chr(x.val) as letter
from xmltable(
'for $i in xs:integer($startLetter)
to xs:integer($endLetter)
return $i'
passing ascii('A') as "startLetter"
, ascii('Z') as "endLetter"
columns val number path '.'
) x
)
select *
from blist
order by letter
NR | LETTER | 65 | A | 66 | B | 67 | C | 68 | D | 69 | E | 70 | F | 71 | G | 72 | H | 73 | I | 74 | J | 75 | K | 76 | L | 77 | M | 78 | N | 79 | O | 80 | P | 81 | Q | 82 | R | 83 | S | 84 | T | 85 | U | 86 | V | 87 | W | 88 | X | 89 | Y | 90 | Z |
---|