首页 > 解决方案 > Sql 列值作为选择中的公式

问题描述

我可以根据作为公式列出的另一列的值来选择一列吗?所以我有一张桌子,比如:

column_name    formula     val
one            NULL        1
two            NULL        2
three          one + two   NULL

我想做

SELECT
    column_name,
    CASE WHEN formula IS NULL
        val
    ELSE 
        (Here's where I'm confused - How do I evaluate the formula?)
    END as result
FROM
   table

最后得到一个结果集

column_name   result
one           1
two           2
three         3

标签: sqlsql-serversql-server-2008-r2

解决方案


您一直在说列和列名,但实际上您是在谈论行,而不是列。

问题是您(可能)希望每一行都有不同的公式。例如,第 4 行可能是 (2 - one) = 1 或什至 (3 + one) = 4,其中您必须先计算第 3 行,然后才能执行第 4 行。这意味着解析公式将很难做到,它必须能够处理每种类型的公式,即使这些公式引用了其他公式,这只会使它变得更难。

如果您必须能够处理像 (2 + 一) * 五 = 15 和二 + 一 * 五 = 7 这样的函数,那么您基本上是在重新实现一个完整的 eval 函数。最好将 SQL 表返回到另一种内置了 eval 函数的语言,或者如果它必须在 SQL 中,则可以使用 SQL Eval.net 之类的东西。

但是,无论哪种方式,您仍然必须将“2 + 1”更改为“2 + 1”,然后才能使用它进行评估。由于这些值位于其他行中,因此您无法在正在查看的行中看到这些值。要获得“一个”的值,您必须执行类似的操作

Select val from table where column_name = 'one'

即便如此,如果 val 为空,这意味着它还没有被计算出来,你必须稍后再回来重试。

如果我必须做这样的事情,我会创建一个临时表,并将基本表加载到其中。然后,我将遍历具有空值的行,尝试用文字值替换列名。我会在任何不再有符号的公式上运行 eval,为这些行设置 val。如果仍然有没有 val 的行(即他们正在等待另一行先完成),我会返回并再次迭代。最后,您应该为每一行都有一个 val,此时它是一个简单的查询来获取您的结果。


推荐阅读