【问题标题】:optimizing the sql query by not repeating the math通过不重复数学来优化 sql 查询
【发布时间】:2023-03-27 21:29:01
【问题描述】:

这是我试图从中删除冗余数学运算的 Oracle 查询:

选择名称,

     CASE 
       when nvl(num1,0) + nvl(num2,0) - nvl(num3,0) > 0
       THEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0)
       ELSE 0
      END
      as result,
      .... from ....

上面的总结怎么不重复?

“结果”应包含 - 上述表达式的值 if > 0

                    -  0 if the value of expression is <= 0.

【问题讨论】:

  • 您确定这实际上是导致查询出现问题的原因吗?将 THEN 更改为 1 而不是总和,看看它是否真的有所作为。否则,您将白费力气地进行所有这些努力

标签: sql oracle math case


【解决方案1】:

在这种情况下,您可以将 CASE 表达式替换为:

GREATEST( nvl(num1,0) + nvl(num2,0) - nvl(num3,0), 0 )

OrbMan 的回答通常更有用。

【讨论】:

    【解决方案2】:

    使用派生表:

    select name, nvl(CASE when sumall > 0 THEN sumall end, 0) as result
    from (
        select nvl(num1,0) + nvl(num2,0) - nvl(num3,0) sumall, name
        from MyTable
    ) a
    

    【讨论】:

    • 为什么不做子查询:select nvl(num1, 0)+nvl(num2, 0) + nvl(num3, 0) sumof3nums, name from MyTable
    • 嗯,为什么顶级查询中需要nvl?是否有可能为 null 或 sumall
    • @Frus: 因为没有ELSE 子句,当第一个case 不匹配时,case 语句将返回NULL。它可以用ELSE 子句代替,结果相同。
    【解决方案3】:

    假设您出于性能原因想要摆脱数学,最好的方法(从 DBA 的角度来看)是创建另一个名为 result 的列,然后使用插入/更新触发器自动填充当一行发生变化时,使用你想要的值:

    CASE 
       WHEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0) > 0
       THEN nvl(num1,0) + nvl(num2,0) - nvl(num3,0)
       ELSE 0
    END
    

    这样,计算仅在需要时进行(在行创建/更改时),而不是每次读取。这分摊了读取次数多于写入次数的数据库的操作成本(根据我的经验,这与所有数据库都接近)。

    那么你的查询就变得简单而快速:

    select name, result from ...
    

    此方法有效,因为:

    • 绝大多数数据库确实阅读频率远高于写入频率;和
    • 磁盘空间比 CPU grunt 便宜(比较有关数据库性能的数据库问题与有关存储要求的问题 - 前者大大超过后者)。
    • 具有每行函数的数据库查询很少随着表变大而很好地扩展。

    当然,这一切都假设 Oracle 具有 触发器。我自己是一个 DB2 人,但如果 Oracle 如此脑残以至于没有它们,我会感到惊讶。再说一次,据我所知,也许 Oracle 仍然 无法区分 NULL 和空字符串,所以谁知道呢? :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      相关资源
      最近更新 更多