Итоговая активность транзакций в SQL - PullRequest
2 голосов
/ 30 августа 2011

Я работаю с таблицей транзакций.Я хочу сгенерировать ряд переменных, чтобы определить количество транзакций, выполненных одним и тем же клиентом за последние 5 и 30 минут, а также 1,2,3 и 4 часа, 1,2,5 и 10 дней.Как эффективно создать такие столбцы в таблице транзакций?- Решение будет иметь промежуточный итог до каждой транзакции.У меня есть Oracle и другие варианты SQL в моем распоряжении.

Ответы [ 2 ]

1 голос
/ 30 августа 2011

Я не думаю, что вы хотите хранить эти статистические данные физически, так как они будут постоянно меняться из-за их временной природы. Решение действительно зависит от того, как вы будете использовать эту статистику. Я могу придумать 2 основных способа:

  1. Специальные запросы для данного уникального клиента - в этом случае у меня будет хранимая процедура, принимающая идентификатор клиента и таймфрейм в качестве параметров, и возвращающая соответствующее количество транзакций на клиента.

  2. «Стандартизированная» отчетность для нескольких клиентов в нескольких окнах. В этом случае вам, вероятно, нужно иметь представление за период времени, выбирающее всех клиентов и количество транзакций на клиента за соответствующий период времени.

Возможно, если вы сможете дать нам больше информации о ваших сценариях использования, мы сможем быть более конкретными.

0 голосов
/ 31 августа 2011

Для одного клиента:

Лучшее решение, которое я могу придумать, - это не использование аналитики, а субфакторные запросы / общие табличные выражения. Oracle, как правило, достаточно умен, чтобы знать, превращать ли их во временную таблицу или нет, что снижает стоимость обработки нескольких передач по одним и тем же данным.

with txns as 
       (select customer_id
               txn_id,
               txn_ts
          from transaction_table
         where customer_id = ?
           AND txn_ts >= SYSTIMESTAMP - NUMTODSINTERVAL(10, 'DAY')
       )
select customer_id,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(5/1440, 'day')) 
         as txn_5_min,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(30/1440, 'day')) 
         as txn_30_min,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(1/24, 'day')) 
         as txn_1_hour,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(2/24, 'day')) 
         as txn_2_hour,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(3/24, 'day')) 
         as txn_3_hour,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(4/24, 'day')) 
         as txn_4_hour,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(1, 'day')) 
         as txn_1_day,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(2, 'day')) 
         as txn_2_day,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(5, 'day')) 
         as txn_5_day,
       (select count(*) from txns 
         where event_ts >= systimestamp - numtodsinterval(10, 'day')) 
         as txn_10_day
  from customer
 WHERE customer_id = ?;

Вы могли бы использовать аналогичную реализацию для случая с несколькими клиентами, хотя эффективность определенно пострадает. Подумайте, будут ли ваши 5-минутные данные уровня устаревшими для всех клиентов к тому времени, как вы закончили их получение.

...