我有两个表tab_a作为
[
{
"name": "spt_fallback_db",
"object_id": 117575457,
"principal_id": null,
"schema_id": 1,
"parent_object_id": 0,
"type": "U ",
"type_desc": "USER_TABLE",
"create_date": "2003-04-08T09:18:01.557",
"modify_date": "2017-08-22T19:40:40.763",
"is_ms_shipped": true,
"is_published": false,
"is_schema_published": false,
"lob_data_space_id": 0,
"filestream_data_space_id": null,
"max_column_id_used": 8,
... etc
2个表的tab_b为
SUB_ID AMOUNT
1 10
2 5
3 7
4 15
5 4
slab_start将始终比上一个slab_end的slab_end多
如果运行tab_a的运行总计,则结果为
slab_number slab_start slab_end
1 12 20
2 21 25
3 26 35
我需要进行SQL查询,以检查run_sum小于第一个slab_number时,哪个slab_NUMBER应该为零;如果run_sum大于最后一个slab_number,则为空白,但超出限制的行除外。 预期结果是
select sub_id , sum(amount) OVER(ORDER BY sub_id) run_sum
from tab_a
sub_id run_sum
1 10
2 15
3 22
4 37
5 41
我已经尝试过了。
首先找到超出限制i的运行总和。最后一个slab_end
sub_id run_sum slab_number
1 10 0
2 15 1
3 22 2
4 37 3
5 41 NULL
然后在下面的查询中使用
select min( run_sum )
from (select sub_id , sum(amount) OVER(ORDER BY sub_id) run_sum
from tab_a ) where run_sum>=35
还有其他改进方法吗?
答案 0 :(得分:0)
您可以尝试以下方法:
select a.sub_id , sum(a.amount) OVER(ORDER BY a.sub_id) run_sum
,case when b.slab_number=1 then 0 else lag(b.slab_number,1) over (order by a.sub_id)end slab_number
from tab_a a
left join tab_b b on a.SUB_ID = b.slab_number
答案 1 :(得分:0)
有些奇怪的要求:)使用一些解析函数和case when
。 Row_number
,当您需要 first ,max() over()
和sum() over()
,当您需要从多行中获取信息时:
with
a as (
select sub_id, row_number() over (order by sub_id) rn,
sum(amount) over (order by sub_id) rs
from tab_a),
b as (select tab_b.*, max(slab_number) over () msn from tab_b )
select sub_id, rs,
case when sn is null and row_number() over (partition by sn order by sub_id) = 1
then msn else sn
end sn
from (
select sub_id, rs, max(msn) over () msn,
case when slab_number is null and rn = 1 then 0 else slab_number end sn
from a left join b on rs between slab_start and slab_end)
答案 2 :(得分:0)
我认为这基本上是一个带有默认值的left join
:
select a.*,
(case when a.run_sum < bb.min_slab_num then 0
else b.slab_num
end) as slab_num
from (select sub_id,
sum(amount) over (order by sub_id) as run_sum
from tab_a
) a left join
tab_b b
on a.run_sum between slab_start and slab_end cross join
(select min(slab_start) as min_slab_start
from tab_b
) bb;