这是一个编写效率低下的嵌套游标.你能用一个更有效的查询来代替它并解释我的问题吗



这是我在一个项目上遇到的一个问题,我只想看看其他人对它有什么看法。基本上,我需要弄清楚它试图做什么,并用一个更高效的查询取代它:

declare @Totalunitamount money   
declare @addamount money   
Declare @unithold int   
declare @oloop int   
DECLARE Jack_CursorOut CURSOR FOR SELECT h.salesorderid FROM SalesOrderHeader h
OPEN Jack_CursorOut;   
FETCH NEXT FROM Jack_CursorOut into @unithold;  
set @Totalunitamount = 0  
set @oloop= @@fetch_status   
        DECLARE Jack_CursorIn CURSOR for select d.unitprice from   
    SalesOrderDetail d where d.salesorderid=@unithold    
    open Jack_CursorIn;    
        set @Totalunitamount=0    
        FETCH NEXT FROM Jack_CursorIn into @addamount;    
        WHILE @@FETCH_STATUS = 0    
        begin    
        set @Totalunitamount= @Totalunitamount+@addamount    
            FETCH NEXT FROM Jack_CursorIn into @addamount;   
        end     
    print 'Order number ' + convert(varchar,@unithold,1) + ' Order Total=' +
    convert(varchar,@Totalunitamount,1)
        CLOSE Jack_CursorIn;   
        DEALLOCATE Jack_CursorIn;   
WHILE @oloop=0   
begin   
FETCH NEXT FROM Jack_CursorOut into @unithold;
set @oloop= @@fetch_status

使用两个游标和一个while循环执行以下操作看起来过于复杂:

SELECT h.salesorderid, SUM(d.unitprice) OrderTotal 
FROM SalesOrderHeader h 
JOIN SalesOrderDetail d ON d.salesorderid = h.salesorderid
GROUP BY h.salesorderid

或者,更具体地说,打印由上述查询产生的每一行的串联。

可能还需要一个ISNULL(SUM(d.unitprice), 0)语句,在没有单位订单的情况下,如果这真的很重要的话。

看起来第一个光标使用@unithold按ID遍历所有销售订单。

然后,内部光标依次遍历每个销售订单上的行项目,并使用@Totalunitamount获取该销售订单上所有行项目的总成本。

输出是每个销售订单ID及其总成本的列表。

在没有数据库/样本数据的情况下进行逆向工程是很棘手的,因为很容易错过一些模糊的细节,但看起来实际数据(无论输出表现如何)可以通过类似于的东西获取

SELECT h.salesorderid "Order Number", SUM(d.unitprice) "Order Total"
  FROM SalesOrderHeader h, SalesOrderDetail d
 WHERE d.salesorderid = h.salesorderid
 GROUP BY h.salesorderid

真的,这一切都有点奇怪,因为它写得太奇怪了。此外,它似乎可以评估所有订单,无论日期、状态、客户、商店或任何其他因素如何。