SQL:Return 不同的 SUM 取决于 CASE

SQL: Return different SUM depending on CASE

我有两个 table 具有 Header/Detail 关系,我正在创建一个视图。
视图上的其中一列的计算(OrderQty)取决于所听到的其中一列的值table(Status)。
所以根据 Status 我希望 OrderQty 是不同字段的总和,这就是我尝试过的:

       (CASE
             WHEN so.Status = 10 THEN (SELECT SUM(sod.OrderQty - sod.BackOrderQty - sod.CancelQty) AS v
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 20 THEN (SELECT SUM(sod.DespatchQty)
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 30
               OR so.Status = 40 THEN (SELECT SUM(ISNULL(sod.PODQty, sod.DespatchQty))
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 50
               OR so.Status = 60 THEN (SELECT SUM(sod.InvoiceQty)
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
        END) AS OrderQty;

整体观点是:

SELECT so.SalesOrderID,
       so.SalesOrderJobTypeID,
       so.CarrierCodeID,
       so.SalesOrderTransportStatusID,
       so.CollectionDateTime,
       so.CustomerReference,
       so.FileReference,
       so.RequiredDate,
       so.SpecialInstructions,
       so.DeliveryNotes,
       dbo.ufn_SO_DecodeSOHeaderStatus(so.Status) AS Status,
       so.TransportCost,
       so.TransportRevenue,
       so.CurrencyCode,
       customer.AccountCode,
       customer.CustomerName,
       customer.Address1,
       customer.Address2,
       customer.Address3,
       customer.Address4,
       customer.PostCode,
       (SELECT UserName
        FROM dbo.SecurityUser
        WHERE dbo.SecurityUser.UserID = so.CreatedByUserID) AS CreatedByUser,
       (SELECT WeekNumber
        FROM dbo.Calendars
        WHERE dbo.Calendars.Date = so.RequiredDate) AS WeekNumber,
       (MONTH(so.RequiredDate)) AS MonthNumber,
       (SELECT ShortCode
        FROM dbo.StoreCodes
        WHERE dbo.StoreCodes.StoreCodeID = so.StoreCodeID) AS StoreCode,
       ISNULL((SELECT PickedQty
               FROM dbo.SO_SOAllocatedContainersView
               WHERE dbo.SO_SOAllocatedContainersView.SalesOrderID = so.SalesOrderID),
              0) AS PickedQty,
       (CASE
             WHEN so.Status = 10 THEN (SELECT SUM(sod.OrderQty - sod.BackOrderQty - sod.CancelQty) AS v
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 20 THEN (SELECT SUM(sod.DespatchQty)
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 30
               OR so.Status = 40 THEN (SELECT SUM(ISNULL(sod.PODQty, sod.DespatchQty))
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
             WHEN so.Status = 50
               OR so.Status = 60 THEN (SELECT SUM(sod.InvoiceQty)
                                       FROM dbo.SalesOrderDetail sod
                                       WHERE sod.SalesOrderID = so.SalesOrderID
                                         AND sod.Status <> 99)
        END) AS OrderQty
FROM dbo.SalesOrderHeader so
     JOIN dbo.Customer customer ON so.CustomerID = customer.CustomerID;

这给出了错误:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
有谁了解我正在尝试做的事情并可以提供解决方案吗?

显然这是不正确的table,但是您应该可以采用以下方法:

加入您的 SalesOrderDetail table 使用通用条件并对所需列求和,然后在更简单的案例表达式中使用结果。

使用appy()

...
from dbo.SalesOrderHeader so
join dbo.Customer customer on so.CustomerID = customer.CustomerID
outer apply (
    select Sum(OrderQty) OrderQty, Sum(BackOrderQty) BackOrderQty ... etc
    from dbo.SalesOrderDetail sod
    where sod.SalesOrderID = so.SalesOrderID
    and sod.Status <> 99
)sod;

那么你的情况就变成了

case 
  when so.status = 10 then sod.OrderQty - sod.BackOrderQty - sod.CancelQty 
  when so.status = 20 then sod.DespatchQty
  ... etc
end