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() 子句的条件定义的主要内容,如果未能解决你的问题,请参考以下文章

Oracle Where(条件)子句用法

Oracle Where(条件)子句用法

Merge:探讨on子句和when not match子句的陷阱

JOIN 子句中的条件是邪恶的 SQL

从条件表中获取 WHERE 子句的条件

在 from 子句 *and* where 子句中添加连接条件使查询更快。为啥?