我有一张桌子:
表1
rank value
1 10
25 120
29 130
99 980
我必须生成下表:
表2
rank value
1 10
2 10
3 10
4 10
5 10
6 10
7 10
8 10
9 10
10 10
11 10
12 10
13 120
14 120
15 120
.
.
.
.
25 120
26 120
27 130
28 130
29 130
30 130
.
.
.
.
.
62 980
63 980
.
.
.
99 980
100 980
因此,table2应该具有从1到100的所有值。有3种情况:
答案 0 :(得分:3)
类似
-- your testdata
with table1(rank,
value) as
(select 1, 10
from dual
union all
select 25, 120
from dual
union all
select 29, 130
from dual
union all
select 99, 980
from dual),
-- range 1..100
data(rank) as
(select level from dual connect by level <= 100)
select d.rank,
min(t.value) keep(dense_rank first order by abs(t.rank - d.rank) asc, t.rank desc)
from table1 t, data d
group by d.rank;
答案 1 :(得分:0)
您可以使用交叉连接。使用以下查询来获得结果
select t1.* from table1 t1
cross join
(select * from table1) t2
on (t1.rank=t2.rank);
希望你明白了
答案 2 :(得分:0)
如果我理解您的需要,您可以使用以下内容:
select num, value
from (
select num, value, row_number() over (partition by num order by abs(num-rank) asc, rank desc) as rn
from table1
cross join ( select level as num from dual connect by level <= 100) numbers
)
where rn = 1
这会将你的表与[1,100]区间连接起来,然后只保留每个数字的第一行,按差异排序,并保持相等差异的最大值。
答案 3 :(得分:0)
使用您的表加入分层数字生成器,并使用带有lag()
子句的ignore nulls
:
select h.rank, case when value is null
then lag(value ignore nulls) over (order by h.rank)
else value
end value
from (select level rank from dual connect by level <= 100) h
left join t on h.rank = t.rank
order by h.rank
测试:
with t(rank, value) as (
select 1, 10 from dual union all
select 25, 120 from dual union all
select 29, 130 from dual union all
select 99, 980 from dual )
select h.rank, case when value is null
then lag(value ignore nulls) over (order by h.rank)
else value
end value
from (select level rank from dual connect by level <= 100) h
left join t on h.rank = t.rank
order by h.rank
RANK RANK
---------- ----------
1 10
2 10
...
24 10
25 120
26 120
27 120
28 120
29 130
30 130
...
98 130
99 980
100 980
答案 4 :(得分:0)
这是一个不需要交叉连接的替代方案(但确实使用了一些分析函数,因此您需要测试这是否比您的数据集更高效)其他解决方案):
WITH sample_data AS (SELECT 1 rnk, 10 VALUE FROM dual UNION ALL
SELECT 25 rnk, 120 VALUE FROM dual UNION ALL
SELECT 29 rnk, 130 VALUE FROM dual UNION ALL
SELECT 99 rnk, 980 VALUE FROM dual)
SELECT rnk + LEVEL - 1 rnk,
CASE WHEN rnk + LEVEL - 1 < rnk + (next_rank - rnk)/2 THEN
VALUE
ELSE next_value
END VALUE
FROM (SELECT rnk,
VALUE,
LEAD(rnk, 1, 100 + 1) OVER (ORDER BY rnk) next_rank,
LEAD(VALUE, 1, VALUE) OVER (ORDER BY rnk) next_value
FROM sample_data)
CONNECT BY PRIOR rnk = rnk
AND PRIOR sys_guid() IS NOT NULL
AND LEVEL <= next_rank - rnk;
RNK VALUE
---------- ----------
1 10
2 10
... ...
12 10
13 120
... ...
24 120
25 120
26 120
27 130
28 130
29 130
30 130
... ...
63 130
64 980
65 980
... ...
98 980
99 980
100 980
N.B,我不确定你为什么62和63的值为980 - 29到99之间的中点是64.
此外,您还会看到我使用100 + 1
代替101
- 这是因为如果您想要对事物进行参数设置,则应将100
替换为v_max_rank + 1
参数 - 例如 Title Firstname Lastname Telephone Initial Gender More columns
1 Mr Adam Smith 001
2 Mrs Angela Evans 002 AE
3 Mr Bill Towny 003
4 Miss Dame Beaut 004