Я внес правку. Интересно, как лучше всего хранить и просматривать записи, если я хочу, чтобы в столбце также была группа клиентов. Будет ли по-прежнему возможно сохранить значения, как вы предложили, и создать простое представление?
Здесь отредактированный вопрос: Я хочу иметь статистическую таблицу в Oracle. Таблица должна выглядеть так: РЕДАКТИРОВАТЬ
CustomerGroup может быть, например, группой из Customer3, Customer4 и Customer5. Интересно, как лучше всего хранить такую таблицу. Я имею в виду, лучше ли создать именно такую таблицу, как указано выше, или можно достичь цели с помощью представления?
Но как лучше всего хранить значения в таблицах и как следует создавать представление? Или есть лучший способ для таких вещей?


С моей точки зрения, таблица не должна выглядеть так. Вы бы представили это пользователям в такой табличной форме, чтобы ее было легче читать, но для хранения данных в таблице я бы предложил что-то вроде этого:
create table statistic
(statistic_id number primary key,
customer_id number constraint fk_st_cust references customer,
article varchar2(20),
year number(4),
month number(2) constraint ch_st_mon check (month between 1 and 12),
amount number
);
Я не знаю, какие значения на самом деле представляют (должен ли article быть внешним ключом для другой таблицы? Что такое amount?) и какие ограничения к нему следует применять (например, действителен ли год 2854? Может ли сумма быть отрицательной?). Сколько строк вы можете иметь на месяц/год/клиента?
Тогда просмотр будет
create or replace view v_statistic as
select c.customer_name,
s.year,
s.article,
sum(case when month = 1 then s.amount else 0 end) january,
sum(case when month = 2 then s.amount else 0 end) february,
...
sum(case when month = 12 then s.amount else 0 end) december
from statistic s join customer c on c.customer_id = s.customer_id
group by c.customer_name, s.year, s.article
Возможно, это придется изменить в зависимости от фактических данных и требований, но вкратце я бы это сделал именно так.
Вы можете использовать условную агрегацию с ROLLUP:
CREATE VIEW table_name_statistics (year, username, type, jan, feb, mar) AS
SELECT EXTRACT(YEAR FROM datetime) AS year,
username,
CASE
WHEN GROUPING_ID(type) = 1
THEN 'sum'
ELSE type
END AS type,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM datetime) = 1 THEN 1 END), 0) AS jan,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM datetime) = 2 THEN 1 END), 0) AS feb,
COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM datetime) = 3 THEN 1 END), 0) AS mar
FROM table_name t
GROUP BY
EXTRACT(YEAR FROM datetime),
username,
ROLLUP(type)
ORDER BY
year,
username,
t.type NULLS LAST
Что для примера данных:
CREATE TABLE table_name (datetime, username, type) AS
SELECT DATE '2023-01-01', 'Customer1', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-02-01', 'Customer1', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-03-01', 'Customer1', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-01-01', 'Customer1', 'Article2' FROM DUAL UNION ALL
SELECT DATE '2023-02-01', 'Customer1', 'Article2' FROM DUAL UNION ALL
SELECT DATE '2023-03-01', 'Customer1', 'Article2' FROM DUAL UNION ALL
SELECT DATE '2023-01-01', 'Customer2', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-02-01', 'Customer2', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-03-01', 'Customer2', 'Article1' FROM DUAL UNION ALL
SELECT DATE '2023-01-01', 'Customer2', 'Article2' FROM DUAL UNION ALL
SELECT DATE '2023-03-01', 'Customer2', 'Article2' FROM DUAL;
Затем представление выводит:
Пожалуйста, отредактируйте вопрос, включив в него минимально воспроизводимый пример с: утверждениями
CREATE TABLEиINSERTдля существующих таблиц; английское (не кодовое) описание логики, которую вы хотите реализовать; ВАША попытка решения; и проблемы/ошибки ВАШЕГО решения. Если вы не сообщите нам, с чего начинаете, как мы сможем найти решение, подходящее для вашего приложения?