【问题标题】:SQL: Adding two summed fields and comparing the summed value with another field valueSQL:添加两个求和字段并将求和值与另一个字段值进行比较
【发布时间】:2012-11-28 23:44:53
【问题描述】:

好的,伙计们关于这个话题的最后一个问题(我希望)。

我需要做的是对两个不同表中的字段求和,将它们加在一起,然后检查这个总数是否大于客户的信用额度。

我已将我的问题分解为较小的任务,以便尝试提出整体解决方案。 (这些较小的代码对我来说可以正常工作,但是在第三段代码中组合时,它们的总和不正确)。首先,我计算了第一个求和字段,如下所示:

 --summmed open invoices

 SELECT company,  sum(unit_price * invoice_qty) as open_invoices

 FROM 
  (SELECT arc.company, ard.unit_price, ard.invoice_qty, arc.credit_limit
   FROM iqms.arprepost_detail ard, iqms.arprepost arp, iqms.arcusto arc
   WHERE ard.arprepost_id = arp.ID
       AND arp.arcusto_id = arc.ID)

 GROUP BY company
 ORDER BY company;

这里的数字在求和时是正确的,我已经手动检查过。接下来我总结了我需要的另一个字段,如图所示:

 --summed open orders

 SELECT company, (sum (unit_price * total_qty_ord)) as total_open_orders

 FROM 
   (SELECT arc.company, od.unit_price, od.total_qty_ord, arc.credit_limit   
    FROM iqms.arcusto arc, iqms.orders o, iqms.ord_detail od
    WHERE od.orders_id = o.ID
       AND o.arcusto_id = arc.ID
       AND (od.cumm_shipped < od.total_qty_ord  OR od.cumm_shipped IS NULL))

 GROUP BY company
 ORDER BY company;

这些数字再次通过人工检查正确显示。

我现在需要将这两个计算加在一起,并检查该数字是否大于该客户的“credit_limit”字段。我为此编写了代码,但数字超出了应有的水平(此代码如下所示)。

 --summmed open invoices + open orders

  SELECT company, credit_limit, 
        round(sum(i_up * invoice_qty)) AS total_invoices, 
        round(sum (o_up * total_qty_ord)) AS total_orders,
        round(sum(i_up * invoice_qty) + sum (o_up * total_qty_ord)) as overall_total

 FROM 
   (SELECT arc.company, arc.credit_limit, ard.unit_price as i_up, ard.invoice_qty, od.unit_price as o_up, od.total_qty_ord 
    FROM iqms.arprepost_detail ard, iqms.arprepost arp, iqms.arcusto arc, iqms.orders o, iqms.ord_detail od
    WHERE 
       ard.arprepost_id = arp.ID      
       AND arp.arcusto_id = arc.ID
       AND od.orders_id = o.ID
       AND o.arcusto_id = arc.ID
       AND (od.cumm_shipped < od.total_qty_ord  OR od.cumm_shipped IS NULL)
   )

 GROUP BY company, credit_limit
 HAVING ((sum(i_up * invoice_qty)) + (sum (o_up * total_qty_ord)) > credit_limit)
 ORDER BY company;

我不确定我哪里出错了。也许这是一个简单的修复,或者我的逻辑有问题。非常感谢任何见解。非常感谢您一直以来的支持。

【问题讨论】:

    标签: sql database oracle sum


    【解决方案1】:

    我的第一个观察是你应该使用explicit joins instead of implicit joins,隐式连接已经过时了 20 年

    您不能像以前那样组合您的 2 个查询,因为它们来自不同的表,使用隐式连接这样做会导致交叉连接。我认为最简单的方法是为每个查询使用 2 个左连接:

    SELECT  arc.Company,
            arc.Credit_Lime,
            COALESCE(Open_Orders, 0) AS Open_Orders,
            COALESCE(Open_Invoices, 0) AS Open_Invoices
            COALESCE(Open_Orders, 0) + COALESCE(Open_Invoices, 0) AS Total_Amount
    FROM    iqms.arcusto arc
            LEFT JOIN
            (   SELECT  o.arcusto_ID
                        SUM(od.unit_price * od.total_qty_ord) AS Open_Orders
                FROM    iqms.orders o
                        INNER JOIN iqms.ord_detail od
                            ON od.orders_ID = o.ID
                WHERE   od.Cumm_Shipped < od.Total_qty_Ord
                OR      od.Cumm_Shipped IS NULL
                GROUP BY o.arcusto_ID
            ) openOrders
                ON openOrders.Arcusto_ID = arc.ID
            LEFT JOIN
            (   SELECT  arp.arcusto_id,
                        SUM(Unit_Price * Invoice_Quantity) AS Open_Invoices
                FROM    iqms.arprepost_detail ard
                        INNER JOIN iqms.arprepost arp
                            ON  ard.arprepost_id = arp.ID
                GROUP BY arp.arcusto_id
            ) OpenInvoices
                ON OpenInvoices.Arcusto_ID = arc.ID
    WHERE   COALESCE(Open_Orders, 0) + COALESCE(Open_Invoices, 0) > arc.Credit_Limit;
    

    您还可以将这两个查询联合如下:

    SELECT  arc.Company,
            arc.Credit_Lime,
            SUM(COALESCE(Open_Orders, 0)) AS Open_Orders
    FROM    iqms.arcusto arc
            LEFT JOIN
            (   SELECT  o.arcusto_ID
                        SUM(od.unit_price * od.total_qty_ord) AS Open_Orders
                FROM    iqms.orders o
                        INNER JOIN iqms.ord_detail od
                            ON od.orders_ID = o.ID
                WHERE   od.Cumm_Shipped < od.Total_qty_Ord
                OR      od.Cumm_Shipped IS NULL
                GROUP BY o.arcusto_ID
                UNION ALL
                SELECT  arp.arcusto_id,
                        SUM(Unit_Price * Invoice_Quantity) AS Open_Invoices
                FROM    iqms.arprepost_detail ard
                        INNER JOIN iqms.arprepost arp
                            ON  ard.arprepost_id = arp.ID
                GROUP BY arp.arcusto_id
            ) OpenInvoices
                ON OpenInvoices.Arcusto_ID = arc.ID
    GROUP BY arc.Company, arc.Credit_Limit
    HAVING  SUM(Open_Orders) > arc.Credit_Limit;
    

    但我认为第一个在确定 Open_Orders 或 Open_Invoices 是否超出信用额度方面提供了更大的灵活性

    【讨论】:

    • 非常感谢伙计,你让我免于崩溃!真的,真的很感激。 :) 谢谢
    【解决方案2】:

    在这种情况下,由于两个查询是不同的,我建议你使用UNION ALL

    SELECT company, SUM(open_invoices) total /*should rename the column in query 1*/ 
      FROM ([QUERY1]
            UNION ALL
            [QUERY2])
     GROUP by company
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-25
      • 2020-11-19
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 2019-10-08
      相关资源
      最近更新 更多