#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;