按位置计算分区其余部分的一半
Posted
技术标签:
【中文标题】按位置计算分区其余部分的一半【英文标题】:Count half of rest of a partition by from position 【发布时间】:2020-05-31 18:49:03 【问题描述】:我正在努力实现以下结果:
现在,该组来自
SUM(CASE WHEN seqnum <= (0.5 * seqnum_rev) THEN i.[P&L] END) OVER(PARTITION BY i.bracket_label ORDER BY i.event_id) AS [P&L 50%],
我需要在每次迭代中计算从末尾到位置 (seq_inv) 的总行数,并仅对从该位置开始的一半计算 P&L 中的金额。
例如,当
seq = 2
seq_inv 将是 = 13,其中一半是 6,所以我需要将 seq = 2 中的以下 6 个位置相加。
当 seq = 4 时有 11 个位置到最后(seq_inv = 11),所以一半是 5,所以我想从 seq = 4 开始计算 5 个位置。
我希望这是有道理的,我正在尝试提出一个能够适应我所拥有的情况的规则,因为分区为我提供了需要求和的数字。
我也在考虑是否与前 50% 或类似的分区有关,但我想这不存在。
【问题讨论】:
不能很好地理解范围。比如黄色的那个,3-8这个范围是怎么发生的? @TheImpaler 从范围 3 到末尾,有 12 行,其中一半是 6,所以我从位置 3 总结了 6 个位置 @Baldie47 。 . .你应该设置一个 dbfiddle. 紫色框是-1
的五行,但结果为3.76
。黄色框是六行-1
和一行0.6
,但结果为10.64
。对于难以描述的要求,必须示例数据和示例结果实际上是正确的。
【参考方案1】:
我的优势是我以前帮助过他,并且有一点额外的背景。
上下文是,这只是很长的公用表表达式链的后期阶段。这意味着不幸的是,自联接和/或相关子查询很昂贵。
最好使用窗口函数来回答,因为数据集已经以适当的顺序和分区可用。
我的阅读是这样的......
SUM(5:9)
(表示第 5 行到第 9 行之和,含) 等于SUM(5:end) - SUM(10:end)
这让我想到了这个……
WITH
cumulative AS
(
SELECT
*,
SUM([P&L]) OVER (PARTITION BY bracket_label ORDER BY event_id DESC) AS cumulative_p_and_l
FROM
data
)
SELECT
*,
cum_val - LEAD(cumulative_p_and_l, seq_inv/2, 0) OVER (PARTITION BY bracket_label ORDER BY event_id) AS p_and_l_50_perc,
cum_val - LEAD(cumulative_p_and_l, seq_inv/4, 0) OVER (PARTITION BY bracket_label ORDER BY event_id) AS p_and_l_25_perc,
FROM
cumulative
注意:在列名中使用、
&
、%
是非常可怕的,不要这样做;)
编辑:更正了累积和中的ORDER BY
。
【讨论】:
【参考方案2】:我不认为窗口函数可以做你想做的事。您可以改用相关子查询,其逻辑如下:
select
t.*,
(
select sum(t1.P&L]
from mytable t1
where t1.seq - t.seq between 0 and t.seq_inv/2
) [P&L 50%]
from mytable t
【讨论】:
我真的不知道如何实现这个,我正在尝试,我应该在这里添加分区似乎有意义吗? 根据样本数据,这个答案是正确的。 我已经添加了代码,但结果显然对所有行都进行了计数,而不仅仅是我想要的那些,因为给我的结果超过 700(当值应该在 2 到 10 左右时)跨度> @GMB 我认为窗口函数可以做到这一点。sum of rows 5 to 9
等于 sum of rows 5 to infinity
减去 sum of rows 10 to infinity
?那么,在一个 CTE 中,创建一个累积和列,在下一个 CTE 中使用LEAD()
查找并扣除适当的值? (这感觉措辞不好,这里有一个答案,比我更聪明的人可以同行评议)以上是关于按位置计算分区其余部分的一半的主要内容,如果未能解决你的问题,请参考以下文章