Эффективный алгоритм хранения данных для подсчета значения Rolling Quarter - PullRequest
0 голосов
/ 08 июня 2011

Рассмотрим набор данных с данными за 6 месяцев следующим образом:

// Month-01 = 1
// Month-02 = 5
// Month-03 = 3
// Month-04 = 2
// Month-05 = 7
// Month-06 = 8

Тогда скользящий квартал (сумма последних 3 месяцев) будет выглядеть следующим образом:

// QTR-01 = N/A
// QTR-02 = N/A
// QTR-03 = 9
// QTR-04 = 10
// QTR-05 = 12
// QTR-06 = 17

Теперь неэффективный алгоритм для этого вычисления в SQL выглядит следующим образом (не идеальный алгоритм, просто рассмотрите тему алгоритма, пожалуйста):

foreach row { id,month,qtr,... } in database.table
{
  qtrValue = select sum( top 3 month) from database.table where table.id = row.id;
  update row.qtr set row.qtr= qtrValue;
}

Можете ли вы предложить эффективный алгоритм и / или проект хранилища данных для этой проблемы? Неважно, включает ли это реляционную базу данных или нет.

Ответы [ 2 ]

0 голосов
/ 08 июня 2011

Функция агрегирования окна Moving SUM будет выполнять то, что вы хотите сделать.

Что-то вроде этого:

SELECT SUM(Month) 
       OVER(ROWS BETWEEN 2 PRECEDING AND CURRENT ROWS)
FROM database.table

Существует опция PARTITION BY, которая позволяет вам применятьагрегация в группу столбцов.Точный синтаксис может варьироваться в зависимости от платформы базы данных, с которой вы работаете.Если ваша платформа базы данных не поддерживает агрегаты окон, вся надежда не потеряна, но для выполнения той же задачи в нотации на основе набора потребуется немного больше SQL.

0 голосов
/ 08 июня 2011

Что ж, у моего измерения даты просто есть MonthNumberInEpoch, которое является инкрементом увеличения для каждого календарного месяца, начинающегося в эпоху dimDate.

Итак, я могу написать что-то вроде:

with
q_00 as (-- sales monthly
  select
      MonthNumberInEpoch
    , sum (SaleAmount) as SalesMonthly
  from dbo.factSale  as f
  join dbo.dimDate   as d on d.DateKey = f.DateKey
  group by MonthNumberInEpoch
)
select
     a.MonthNumberInEpoch
  , (a.SalesMonthly + b.SalesMonthly + c.SalesMonthly) as SalesThreeMonths
from q_00 as a
join q_00 as b on b.MonthNumberInEpoch + 1 = a.MonthNumberInEpoch
join q_00 as c on c.MonthNumberInEpoch + 2 = a.MonthNumberInEpoch
;
...