【问题标题】:Filtering by analytic function results without subquery or subtable按解析函数结果过滤,不带子查询或子表
【发布时间】:2015-07-04 06:33:41
【问题描述】:

我正在从事 SQL 功能有限的 Netsuite 项目。很难测试,因为我基本上是在猜测他们在 GUI 中构建的 SQL。

我想将查询结果过滤为累积和为负值的结果。

以下是有效的 PL/SQL 构造吗(除非有任何小的语法错误)?

 SELECT SUM(amount) OVER(PARTITION BY itemid ORDER BY date ROWS UNBOUNDED
    PRECEDING) AS "sum" FROM table WHERE sum < 0

其次,由于 Netsuite 的限制,以下是有效的构造吗?

 SELECT SUM(amount) OVER(PARTITION BY itemid ORDER BY date ROWS UNBOUNDED 
    PRECEDING) AS "sum" FROM table WHERE SUM(amount) OVER(PARTITION BY itemid
    ORDER BY date ROWS UNBOUNDED PRECEDING) < 0

Oracle 的文档表明这些都不是有效的,过滤分析函数应该通过子查询来完成,但一些谷歌群组和其他网站建议不这样做。然而,大多数人在他们的示例中使用了 RANK() 和 DENSE_RANK() 函数,它们的功能可能不同。

【问题讨论】:

  • 聚合函数不能在WHERE 子句中使用。别名也不能。对于别名,只需在子查询中执行此操作(或重复整个操作 - 最好不要),对于 SUM(amount) 上的过滤只需将您的记录分组并将其放在 HAVING 子句中。
  • 您不能使用 WHERE 或 HAVING 过滤分析函数的结果(因为它是在聚合/HAVING 之后计算的),您必须将其放入派生表中。
  • “但一些 google 群组和其他网站建议不这样做” - 如果他们真的建议这样做,那就错了。

标签: sql oracle oracle11g oracle10g netsuite


【解决方案1】:

要过滤分析函数的结果,您必须使用内联视图(from 子句中的子查询)。

例如,您的查询可能如下所示:

select  *
from    (
            select  itemid,
                    date,
                    sum(amount) over (
                                        partition by itemid
                                        order by date
                                        rows between unbounded preceding
                                                 and current row
                                     ) as run_sum
            from    table
        )
where   run_sum < 0

这将显示所有项目,以及该项目的运行总和小于零的相关日期(如果给定项目有任何此类日期)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多