У меня есть требование рассчитать суммарную статистику, агрегированную по определенным пользовательским периодам времени. В частности, сеть ресторанов работает 24 часа в сутки. Мне нужно рассчитать статистику, например, общий объем продаж по периодам, где периоды «Завтрак», «Обед», «Ужин» и «Ночь». Для этой компании официальный день, за который они отслеживают статистику, начинается после обеда. Таким образом, 24-часовой период, который составляет официальный день, начинается с 8 вечера и длится до 8 вечера по тихоокеанскому времени) на следующий день. Это один период. Другой период - «Ночь», которая длится с 8 вечера до 5:30 утра. Я ставлю эти определения в таблицу под названием «tdef» как так:Oracle основанная на времени аналитика
drop table tdef cascade constraints
;
create table tdef
(
cd char(3) not null,
start_ts date not null,
stop_ts date not null
)
А затем вставить определения в таблицу tdef, которые хранятся как даты, когда дата начала всегда начинается с 1 января 1900 года, и если она охватывает через полночь, то она заканчивается на 2 января 1900 года, как это так,
insert into tdef (start_ts, stop_ts, cd)
values
(
to_date('1900/01/01 20:00:00', 'yyyy/mm/dd hh24:mi:ss'),
to_date('1900/01/02 19:59:59', 'yyyy/mm/dd hh24:mi:ss'),
'24H'
);
insert into tdef (start_ts, stop_ts, cd)
values
(
to_date('1900/01/01 10:30:00', 'yyyy/mm/dd hh24:mi:ss'),
to_date('1900/01/01 13:29:59', 'yyyy/mm/dd hh24:mi:ss'),
'LUN
);
insert into tdef (start_ts, stop_ts, cd)
values
(
to_date('1900/01/01 15:30:00', 'yyyy/mm/dd hh24:mi:ss'),
to_date('1900/01/02 08:29:59', 'yyyy/mm/dd hh24:mi:ss'),
'ON'
);
у меня есть очень большой стол (около 2,5 миллиардов строк), который содержит все операции регистра. Мне нужно суммировать продажи по дате (их определение 8 PM-8PM), размер продукта и времени и хранить это в таблице для быстрого доступа к отчетам. Стол должен выглядеть следующим образом:
Dec 12 2011, Hamburger, 24H, 1000
Dec 12 2011, Hamburger, ON, 100
Dec 12 2011, Hamburger, LUN, 400
Вот что я сделал, чтобы достичь этого, я добавил две даты столбцов в таблице транзакций, которые время сделки по 1/1/1900 и 1/2/1900, например:
to_date(concat('01/01/1900 ', tran_tm), 'mm/dd/yyyy hh24:mi'),
to_date(concat('01/02/1900 ', tran_tm), 'mm/dd/yyyy hh24:mi')
Я проиндексировал эти две колонки. Затем я создал таблицу перекрестного поиска, в которой связаны идентификаторы транзакций с временными кодами. Каждый код транзакции может быть в течение более чем одного раза исправления. Так это выглядит следующим образом:
24H, 1
24H, 2
24H, 3
...
LUN, 100
LUN, 101
LUN, 102
...
ON, 1
ON, 2
...
Я использовал две вставки операторов выбора для достижения этой цели:
select t.trans_id, td.cd, to_date(to_char(to_date(concat(to_char(ts, 'mm/dd/yyyy '), to_char(td.stop_ts, 'hh24:mi:ss')), 'mm/dd/yyyy hh24:mi:ss', 'yyyymmdd'), 'yyyymmdd')
from trans t, tdef td
where ts1 >= td.start_ts and ts1 <= td.stop_ts
select t.trans_id, td.cd, to_date(to_char(to_date(concat(to_char(ts, 'mm/dd/yyyy '), to_char(td.stop_ts, 'hh24:mi:ss')), 'mm/dd/yyyy hh24:mi:ss', 'yyyymmdd'), 'yyyymmdd')
from trans t, tdef td
where ts2 >= td.start_ts and ts2 <= td.stop_ts
Третье поле является «официальной датой». Как это работает, предположим, что транзакция произошла 12/12/2011 20:01, тогда поле ts1 будет 1/1/1900 8:01 PM, а поле ts2 будет 1/2/1900 8:01 PM. В первом запросе это поле присоединяется к cd '24H' и 'ON'. И официальная дата будет рассчитана как 12/13/2011 для «24H» и 12/13/2011 для «ON». Эта транзакция не будет присоединяться к второму запросу, потому что она находится за пределами диапазона дат. Предположим, что транзакция произошла 13.12.2011 13:05. В первом запросе ts1 присоединился бы так: «24H» на дату 12/13/2011, «LUN» на дату 12/13/2011.
После того, как у меня есть эта таблица, легко агрегировать:
select tdef_trans.dt, sum(sales) from trans, tdef_trans where trans.id = tdef_trans.id and tdef_trans.cd = 'LUN'
Хотя это решение, кажется, работает, я готов держать пари, есть более элегантный способ сделать это. Есть идеи?
Это домашнее задание? – eaolson
Нет. Не домашнее задание. Реальная жизнь. Я немного изменил ситуацию, применив концепцию к ресторану, потому что это индустрия, которую, как мне кажется, большинство людей понимают. На практике данные поступают из онлайн-аукционов, которые, по моему мнению, представляют собой более сложный контекст. –