首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游标与While循环- SQLServer

游标与While循环- SQLServer
EN

Stack Overflow用户
提问于 2010-10-26 19:58:30
回答 2查看 4K关注 0票数 6

假设我在DB中有很多行(在本例中是SQLServer 2008 ),这些行可以用来创建方程。

代码语言:javascript
复制
 -----------------------------------------------------
 OperationID | EquationID | Operation | Amount | Order
 -----------------------------------------------------
     1       |     1      |     +     |   12   |  1 
     2       |     1      |     +     |   12   |  2 
     3       |     2      |     /     |   2    |  3 
     4       |     2      |     +     |   12   |  1 
     5       |     2      |     -     |   2    |  2 
 -----------------------------------------------------

我需要想出一种方法来评估这张表中的方程式。

方程1: 12 + 12 = 24

方程2:(12-2)/2=5

我想不出一种在不迭代行的情况下获得这些结果的方法。我知道的唯一方法是使用游标,或者通过使用temp表和while循环。有什么更好的方法吗?如果不是一般情况下,什么将执行更好的游标或同时循环?

注意:这有点简化,在这个项目的这个阶段,我们只能猜测数据会是什么样子。假设每个“等式”将有大约100到1000个操作,每天将有几千个“等式”需要处理。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-26 20:17:44

已经证明,递归CTE的性能比循环要好得多,可以得到运行总计。这只是一个实际使用变量操作符的运行总数,因此性能方面的好处应该适用于这里。

创建行为类似循环的递归CTE的方法如下所示:

代码语言:javascript
复制
        ;WITH cte AS (
        SELECT equation, number, order FROM table WHERE order = 1
        UNION ALL
        SELECT table.equation, 
            CASE WHEN table.operation = '+' THEN cte.number + table.number
                 WHEN table.operation = '-' THEN cte.number - table.number END AS number, --etc.
table.order FROM table INNER JOIN cte ON table.order = cte.order + 1 AND table.equation = cte.equation
        )
    SELECT equation, number, order 
    FROM cte
    OPTION (MAXRECURSION 1000);

第一个选择获取最左边的数字,并且UNION对它返回的数字执行以下操作。Max递归选项将一个方程中的操作数限制为1000。当然,你可以把这个调得更高。

这个答案有点不完整,因为最后的select查询将返回中间结果。不过,这很容易过滤。

票数 3
EN

Stack Overflow用户

发布于 2010-10-26 20:47:58

我已经清理了/充实了一些mootinator's answer,并在这里展示了这些代码。我标记了这个答案社区wiki,因为mootinator的答案值得称赞。这是在不编辑答案的情况下展示代码的最简单的方法。

代码语言:javascript
复制
declare @equations table (
    OperationID int,
    EquationID int,
    Operation char(1),
    Amount int,
    [Order] int
)

insert into @equations
    (OperationID, EquationID, Operation, Amount, [Order])
    values 
    (1, 1, '+', 12, 1),
    (2, 1, '+', 12, 2),
    (3, 2, '/',  2, 3),
    (4, 2, '+', 12, 1),
    (5, 2, '-',  2, 2)

;with cteCalc as (
    select EquationID, Amount, [Order] 
        from @equations 
        where [Order] = 1
    union all
    select e.equationid, 
           case when e.Operation = '+' then c.Amount + e.Amount
                when e.Operation = '-' then c.Amount - e.Amount
                when e.Operation = '*' then c.Amount * e.Amount
                when e.Operation = '/' then c.Amount / e.Amount
           end AS Amount, 
           e.[Order] 
        from @equations e 
            inner join cteCalc c 
                on e.EquationID= c.EquationID
        where e.[Order] = c.[Order] + 1
),
cteMaxOrder as (
    select EquationID, MAX([Order]) as MaxOrder 
        from cteCalc 
        group by EquationID
)
select c.EquationID, c.Amount
    from cteMaxOrder mo
        inner join cteCalc c
            on mo.EquationID = c.EquationID
                and mo.MaxOrder = c.[Order]
    order by c.EquationID
    option (maxrecursion 1000)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4027477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档