Вычислить SUM в операторе T-SQL, который использует CASE для вывода значений - PullRequest
0 голосов
/ 07 июня 2018

У меня есть таблица, содержащая заказы, которые были приобретены на веб-сайте электронной торговли, и вторая таблица с подробным описанием продуктов (по существу, позиций) для каждого заказа.Моя задача - рассчитать общую стоимость и общий вес каждого заказанного продукта, сгруппированные по продуктам.Владелец магазина хочет иметь возможность идентифицировать продукт, который продается больше всего по весу или по стоимости.

Структура двух таблиц выглядит следующим образом:

Заказ

id
orderDate

OrderLine

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, что сводит на нет условную логику weight и total.

Интересно, кто-нибудь может подсказать, как заставить это работать, чтобы я мог вернуть правильные итоги по весу и цене?

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Согласно комментарию @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
0 голосов
/ 07 июня 2018

Я не смог проверить это, но вы должны иметь возможность выполнить подзапрос исходного запроса и применить свою группу по логике к полям общего количества, сохраняя ваши условные выражения в целости.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...