Вы можете сделать итоги магазина / человека во встроенном представлении, которое само по себе производит:
SELECT
StoreId,
PersonId,
Year,
SUM(AmountSpent) AS TotalSpent
FROM table_name
GROUP BY
StoreId,
PersonId,
Year
ORDER BY
StoreId,
Year,
PersonId;
STOREID PERSONID YEAR TOTALSPENT
---------- ---------- ---------- ----------
1 1 2017 110
1 2 2017 10
1 3 2017 25
1 2 2018 200
2 3 2017 200
2 1 2018 70
2 2 2018 60
2 3 2018 200
, а затем использовать несколько отдельных выражений и агрегатов во внешнем запросе:
SELECT
StoreId,
SUM(CASE WHEN Year = '2017'
THEN TotalSpent
ELSE 0
END) Year17,
COUNT(CASE WHEN Year = '2017'
AND TotalSpent < 100
THEN TotalSpent
END) AS Year17lt100,
COUNT(CASE WHEN Year = '2017'
AND TotalSpent >= 100
AND TotalSpent < 150
THEN TotalSpent
END) AS Year17gte100lt150,
COUNT(CASE WHEN Year = '2017'
AND TotalSpent >= 150
THEN TotalSpent
END) AS Year17gte150,
SUM(CASE WHEN Year = '2018'
THEN TotalSpent
ELSE 0
END) Year18,
COUNT(CASE WHEN Year = '2018'
AND TotalSpent < 100
THEN TotalSpent
END) AS Year18lt100,
COUNT(CASE WHEN Year = '2018'
AND TotalSpent >= 100
AND TotalSpent < 150
THEN TotalSpent
END) AS Year18gte100lt150,
COUNT(CASE WHEN Year = '2017'
AND TotalSpent >= 150
THEN TotalSpent
END) AS Year18gte150
FROM (
SELECT
StoreId,
PersonId,
Year,
SUM(AmountSpent) AS TotalSpent
FROM table_name
GROUP BY
StoreId,
PersonId,
Year
)
GROUP BY StoreId
ORDER BY StoreId;
, который получает:
STOREID YEAR17 YEAR17LT100 YEAR17GTE100LT150 YEAR17GTE150 YEAR18 YEAR18LT100 YEAR18GTE100LT150 YEAR18GTE150
---------- ---------- ----------- ----------------- ------------ ---------- ----------- ----------------- ------------
1 145 2 1 0 200 0 0 0
2 200 0 0 1 330 2 0 1
Это не соответствует выводу на вашем изображении, но я думаю, что это неправильно ...
Я также немного изменил сегменты по сравнению с тем, что предлагали заголовки столбцов, но вы можете настроить их, если действительно хотите то, что показали.
Вы также можете уменьшить код и повторение, используя предложение pivot()
, если вы используете версию Oracle, которая поддерживает это; который может обеспечить несколько выходов и также позволяет выполнять условное агрегирование:
SELECT *
FROM (
SELECT
StoreId,
Year,
SUM(AmountSpent) AS TotalSpent
FROM table_name
GROUP BY
StoreId,
PersonId,
Year
)
PIVOT (
SUM(TotalSpent) as total,
COUNT(CASE WHEN TotalSpent < 100 THEN TotalSpent END) as lt100,
COUNT(CASE WHEN TotalSpent >= 100 AND TotalSpent < 150 THEN TotalSpent END) as gte100lt150,
COUNT(CASE WHEN TotalSpent >= 150 THEN TotalSpent END) as gte150
FOR Year IN (2017 as year17, 2018 as year18)
)
ORDER BY StoreId;
STOREID YEAR17_TOTAL YEAR17_LT100 YEAR17_GTE100LT150 YEAR17_GTE150 YEAR18_TOTAL YEAR18_LT100 YEAR18_GTE100LT150 YEAR18_GTE150
---------- ------------ ------------ ------------------ ------------- ------------ ------------ ------------------ -------------
1 145 2 1 0 200 0 0 1
2 200 0 0 1 330 2 0 1
Oracle расширит это, чтобы выглядеть как оригинальный более длинный запрос выше, но его легче поддерживать.
Обновлен SQL Fiddle .