为给定范围生成数字(sql查询)
我正在编写一个在指定范围内生成数字的查询 我有一张桌子为给定范围生成数字(sql查询),sql,oracle,Sql,Oracle,我正在编写一个在指定范围内生成数字的查询 我有一张桌子 NUM_RANGES ID START_NUMBER END_NUMBER -- ------------ ---------- 1 1 5 2 6 10 我需要得到这个结果: ID NUMBER -- ------ 1 1 1 2 1 3 1 4
NUM_RANGES
ID START_NUMBER END_NUMBER
-- ------------ ----------
1 1 5
2 6 10
我需要得到这个结果:
ID NUMBER
-- ------
1 1
1 2
1 3
1 4
1 5
2 6
2 7
2 8
2 9
2 10
通过此查询,我可以得到正确的结果,但仅限于where子句中指定的id:
select id, start_number + level - 1 next_tag
from (select id, start_number,end_number
from NUM_RANGES
where id = 1
)
connect by level <= end_number - start_number + 1
如果没有where id=1,我会得到62行,其中有重复行,而distinct有帮助,但是如果范围更大,则工作速度太慢
谢谢你的帮助 在Oracle 12c上,您可以使用交叉应用:
select *
from num_ranges
cross apply(
select level - 1 + start_number as my_new_number
from dual
connect by level <= end_number - start_number + 1
);
在Oracle 12c上,您可以使用交叉应用:
select *
from num_ranges
cross apply(
select level - 1 + start_number as my_new_number
from dual
connect by level <= end_number - start_number + 1
);
在Oracle 11.2及更早版本中,您可以使用分层查询:
with
num_ranges ( id, start_number, end_number ) as (
select 1, 1, 5 from dual union all
select 2, 9, 12 from dual
)
-- End of simulated input data (for testing purposes only, not part of the solution).
-- SQL query begins below this line.
select id, start_number + level - 1 as nmbr
from num_ranges
connect by level <= end_number - start_number + 1
and prior id = id
and prior sys_guid() is not null
order by id, nmbr -- If needed
;
ID NMBR
---------- ----------
1 1
1 2
1 3
1 4
1 5
2 9
2 10
2 11
2 12
在Oracle 11.2及更早版本中,您可以使用分层查询:
with
num_ranges ( id, start_number, end_number ) as (
select 1, 1, 5 from dual union all
select 2, 9, 12 from dual
)
-- End of simulated input data (for testing purposes only, not part of the solution).
-- SQL query begins below this line.
select id, start_number + level - 1 as nmbr
from num_ranges
connect by level <= end_number - start_number + 1
and prior id = id
and prior sys_guid() is not null
order by id, nmbr -- If needed
;
ID NMBR
---------- ----------
1 1
1 2
1 3
1 4
1 5
2 9
2 10
2 11
2 12
这应该行得通。也很快
with cte as (select 0 as c from dual)
, cte4 as (select c from cte union all select c from cte union all select c from cte union all select c from cte)
, cte256 as (select t0.c from cte4 t0, cte4 t1, cte4 t2, cte4 t3)
, nums as (select row_number() over(order by null) as n from cte256 t0, cte256 t1, cte256 t2)
select NR.id, nums.n as NUMBER_
from nums
join NUM_RANGES NR on nums.n between NR.START_NUMBER and NR.END_NUMBER
;
这应该行得通。也很快
with cte as (select 0 as c from dual)
, cte4 as (select c from cte union all select c from cte union all select c from cte union all select c from cte)
, cte256 as (select t0.c from cte4 t0, cte4 t1, cte4 t2, cte4 t3)
, nums as (select row_number() over(order by null) as n from cte256 t0, cte256 t1, cte256 t2)
select NR.id, nums.n as NUMBER_
from nums
join NUM_RANGES NR on nums.n between NR.START_NUMBER and NR.END_NUMBER
;
你的电话号码需要多高?你的电话号码需要多高?