Ежемесячные итоги Oracle и общий итог по столбцам и строкам

#sql #oracle #pivot

#sql #Oracle #сводная

Вопрос:

Я пытаюсь сгенерировать отчет с использованием Oracle, который выглядит следующим образом:

изображение

Я получил следующие таблицы:

 REGION (IDRegion, Region_Name) 
SALES (IDSale, Sale_Date, Amount, IDSaleRegion)
Both tables are populated.  
  

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

 SELECT Region_Name as Region, 
COALESCE(NULL, NULL) AS "January", 
COALESCE(NULL, NULL)AS"February", 
COALESCE(NULL, NULL)AS"March", 
COALESCE(NULL, NULL)AS"GrandTotal"
FROM REGION r INNER JOIN SALES s ON r.IDRegion=s.IDSaleRegion
GROUP BY Region_Name;
  

РЕДАКТИРОВАТЬ: проблема решена, за исключением ИТОГА (ниже области), который вычисляет итоги за каждый месяц.
Есть идеи, как добавить эту строку?

Комментарии:

1. Нет необходимости делать SELECT DISTINCT , так GROUP BY как возвращает никаких дубликатов.

2. В чем смысл COALESCE(NULL, NULL) ?

3. Я использовал ОБЪЕДИНЕНИЕ только для создания заголовка таблицы…

4. У вас есть какие-то данные для тестирования? Кроме того, какова ваша версия Oracle? Несколько замечаний: с Oracle 11 или выше вы можете использовать операцию PIVOT. Если важна производительность, вам не следует извлекать месяц из Sale_Date — у вас должен быть индекс для этого столбца, и вы должны написать фильтры таким образом, чтобы можно было использовать этот индекс. (Использование «extract» или любой другой функции для него предотвратит использование индекса.) Кроме того, лучше избегать имен столбцов в двойных кавычках, особенно если выходные данные этого запроса используются или могут быть (в будущем) использованы для дальнейшей обработки.

Ответ №1:

Вы можете использовать Conditional Aggregation

 select case grouping(Region_Name) when 1 then 'TOTAL' else Region_Name as "Region",
       sum(case when extract(month from Sale_Date) = 1 then Amount else 0 end) AS "January",
       sum(case when extract(month from Sale_Date) = 2 then Amount else 0 end) AS "February",
       sum(case when extract(month from Sale_Date) = 3 then Amount else 0 end) AS "March",
       sum(Amount) AS"GrandTotal"
From yourtable
Where extract(month from Sale_Date) <= 3
Group by Rollup (Region_Name); 
  

Комментарии:

1. Это работает хорошо! Но как я могу добавить второй итог (ниже регионов) и рассчитать общий итог?

2. @Mr.Gigi — Я отредактировал решение, чтобы ответить на ваш оставшийся вопрос. Пожалуйста, прочитайте о «группировке по сводке» (Google — ваш друг).

Ответ №2:

попробуйте что-то вроде этого:

 SELECT Region_Name as Region, 
sum(decode(extract(month from Sale_Date), 1, amount)) AS "January", 
sum(decode(extract(month from Sale_Date), 2, amount)) AS"February", 
sum(decode(extract(month from Sale_Date), 3, amount)) AS"March", 
sum(case when extract(month from Sale_Date)<4 then amount end) AS"GrandTotal"
FROM REGION r INNER JOIN SALES s ON r.IDRegion=s.IDSaleRegion
GROUP BY Region_Name;