OVER() 子句的条件定义
Posted
技术标签:
【中文标题】OVER() 子句的条件定义【英文标题】:Conditional definition of OVER() clause 【发布时间】:2020-10-12 14:02:53 【问题描述】:假设我有一张表t
,如下所示:
b a v
4 1 1
3 3 2
3 2 3
3 4 4
如何使用带有条件OVER()
子句的分析函数?在下面的示例中,我选择了v
的累积总和。但是,我希望每行累积 v
的前面值,前提是 b
(对于正在考虑求和的每一行)大于“当前”行的 a
。
SELECT SUM(v)
OVER(ORDER BY v ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c
FROM t
应用逻辑会给我以下结果:
c
1
1
6
0
所以我的问题是:是否可以将此逻辑合并到OVER()
子句的定义中?还是我应该考虑另一种方法?
更新
由于这个问题似乎被许多人误解,我将尝试澄清一下。这里重要的是基于比较累积。比较的是 current 行(正在为其计算累积总和的行)中的 a
的值和 b
的值,对于正在“考虑”的每一行累积(前行和当前行)。
我提供的示例恰好具有适合以下if ... then sum else 0
-type 解决方案的格式。我也更新了这个例子,希望能给这个问题带来更多的启发。
【问题讨论】:
"如果b
(对于被考虑求和的每一行)大于“当前”行的a
” - 为什么1,1,6,0
? 3 不大于 3,我想应该是 1,0,6,0
。
你对,我的错。 1, 0, 6, 0
是正确的输出。我已经更新了问题。
一般提供所有v > 0
的条件下不能存在两个或多个相邻相等值的输出。下一个值要么大于前一个,要么为零。
我不确定我是否遵循。如果第一行中b
的值是4
而不是3
,会发生什么?此解决方案仍将产生1, 0, 6, 0
。与条件下的累计和不同。
【参考方案1】:
如果我理解正确,您只需在sum()
中使用case
表达式:
select sum(case when b > a then v end) over (order by a)
from t;
【讨论】:
【参考方案2】:试试
select *,
sum(v) over (order by v) * case when a - min(b) over (order by v) < 0 then 1 else 0 end s
from myTable
fiddle
【讨论】:
【参考方案3】:考虑:
SUM(CASE WHEN b > a THEN v ELSE 0 END) OVER(ORDER BY v) c
编辑
从 cmets 看来,您似乎想要一个外部 case
表达式:
CASE WHEN b > a THNZ SUM(v) OVER(ORER BY v) ELSE 0 END c
【讨论】:
谢谢!但我认为你的回答会产生1, 1, 4, 4
而不是1, 1, 6, 0
。
@CHRD:是的,它将产生什么。我不明白生成1, 1, 6, 0
的逻辑...请逐步解释。
对不起,我在这里犯了一个错误。应该是1, 0, 6, 0
。
再次感谢!虽然这会在特定示例中产生预期结果,但如问题中所述,我正在寻找一种获取累积和的方法(添加了我的条件)。例如,假设我们将第一行中列b
的值从3
更改为4
。此解决方案的结果将相同,而累积和应为1, 1, 6, 0
。
@CHRD:那么您应该创建一个问题,其中包含正确演示您的用例的示例数据、正确的示例数据、期望的结果和解释。您不能让回答者反复猜测和更改答案。【参考方案4】:
以下是 BigQuery 标准 SQL
#standardSQL
select if(b > a, sum(v) over(order by v), 0)
from `project.dataset.table`
【讨论】:
谢谢!看来我的问题被误解了很多。我添加了一个更新,希望可以帮助澄清事情。干杯!以上是关于OVER() 子句的条件定义的主要内容,如果未能解决你的问题,请参考以下文章