【问题标题】:Calculate SUM in T-SQL statement which uses CASE to output values在使用 CASE 输出值的 T-SQL 语句中计算 SUM
【发布时间】:2018-06-08 17:40:13
【问题描述】:

我有一个表格,其中包含已在电子商务网站上购买的订单,还有一个表格,其中详细说明了每个订单的产品(主要是订单项)。我的职责是计算按产品分组的每个订购产品的总成本和总重量。店主希望能够根据重量或价值来识别销量最高的产品。

两张表的结构是这样的:

订购

id
orderDate

订单行

id
orderId
productNodeId
productName
quantity
duration
frequency
subscription
unitPrice
unitWeight

虽然一些订单行是简单的一次性产品(因此很容易计算总计,即总重量为quantity * unitWeight,总成本为quantity * unitCost)其他订单行是订阅,其中总重量将由(duration/frequency) * unitWeight 计算,总成本将为(duration/frequency) * unitCost

我有以下 T-SQL 语句,它使用 CASE 返回总值(在 SQL Server 2008R2 Express 中运行):

SELECT 
  productNodeId AS id, 
  productName AS name, 
  quantity, 
  duration, 
  frequency, 
  subscription, 
  unitPrice,
  CASE   
    WHEN subscription = 1 THEN unitWeight*(duration/frequency)
  ELSE
    unitWeight*quantity
  END AS weight,
  CASE   
    WHEN subscription = 1 THEN unitPrice*(duration/frequency)
  ELSE
    unitPrice*quantity
  END AS total

FROM Order INNER JOIN OrderLine ON Order.id = OrderLine.orderId WHERE orderStatusId = 3

--GROUP BY productNodeId
ORDER BY total DESC

这在一定程度上有效。它输出以下值:

id   |  name     | quantity | duration | frequency  | subscription | unitPrice | weight | total
1105    Option C   1          24          1            1              2.50        18000    60.00
1105    Option C   1          24          2            1              2.50        9000     30.00
1104    Option B   1          24          2            1              2.50        9000     30.00
1105    Option C   1          24          2            1              2.50        10800    30.00
1105    Option C   1          4          1             1              2.50        2000     10.00
1107    Option A   1          0          0             0              2.80        600      2.80
1107    Option A   1          0          0             0              2.80        600      2.80
1121    Option D   1          0          0             0              2.80        400      2.80

最后一部分是对总数求和。但是,我不能只实现上面代码中注释掉的GROUP BY productNodeId 语句,因为它需要聚合subscription 字段,这否定了条件weighttotal 逻辑。

我想知道是否有人可以建议如何让它工作,以便我可以返回正确的重量和价格总计?

非常感谢。

【问题讨论】:

  • 也许我遗漏了什么,但你为什么不把你的案例陈述放在 SUM() 函数中?;
  • 太棒了,效果很好!谢谢:)

标签: tsql sql-server-2008-r2


【解决方案1】:

我无法对此进行测试,但您应该能够对原始查询进行子查询,并将您的分组按逻辑应用于总字段,从而保持您的条件不变。

select id,name,quantity,duration,frequency,subscription,unitprice,weight,sum(total) as sumedtotal

 from (
SELECT 
  productNodeId AS id, 
  productName AS name, 
  quantity, 
  duration, 
  frequency, 
  subscription, 
  unitPrice,
  CASE   
    WHEN subscription = 1 THEN unitWeight*(duration/frequency)
  ELSE
    unitWeight*quantity
  END AS weight,
  CASE   
    WHEN subscription = 1 THEN unitPrice*(duration/frequency)
  ELSE
    unitPrice*quantity
  END AS total

FROM Order INNER JOIN OrderLine ON Order.id = OrderLine.orderId WHERE orderStatusId = 3

--GROUP BY productNodeId
) as x
group by id,name,quantity,duration,frequency,subscription,unitprice,weight

【讨论】:

  • 非常感谢您的回答。它可能很好用,但我尝试了安东尼在对原始问题的评论中提出的建议,效果很好,而且看起来更简单一些。不过谢谢 - 感谢您的回答。
【解决方案2】:

根据@Anthony Hancock 的评论,最简单的解决方案是将CASE 条件包装在SUM 聚合器中,如下所示:

SELECT 
  productNodeId AS id, 
  MAX(productName) AS name, 
  SUM(CASE   
    WHEN subscription = 1 THEN unitWeight*(duration/frequency)
  ELSE
    unitWeight*quantity
  END) AS weight,
  SUM(CASE   
    WHEN subscription = 1 THEN unitPrice*(duration/frequency)
  ELSE
    unitPrice*quantity
  END) AS total

FROM Order INNER JOIN OrderLine ON Order.id = OrderLine.orderId WHERE orderStatusId = 3
GROUP BY productNodeId
ORDER BY total DESC

【讨论】:

    猜你喜欢
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2015-02-11
    相关资源
    最近更新 更多