расчет изменения (за период) для датированного поля - PullRequest
1 голос
/ 26 мая 2010

У меня есть две таблицы со следующей схемой:

CREATE TABLE sales_data (
     sales_time date NOT NULL,
     product_id integer NOT NULL,
     sales_amt double NOT NULL
);

CREATE TABLE date_dimension (
  id integer  NOT NULL,
  datestamp   date NOT NULL,
  day_part    integer NOT NULL,
  week_part   integer NOT NULL,
  month_part  integer NOT NULL,
  qtr_part    integer NOT NULL, 
  year_part   integer NOT NULL, 
);

Я хочу написать два типа запросов, которые позволят мне рассчитать:

  • период смены периода (например, неделя на неделе)
  • изменение периода при изменении периода (например, изменение недели при изменении недели)

Я бы предпочел написать это в ANSI SQL, поскольку я не хочу привязываться к какой-либо конкретной базе данных.

[Изменить]

В свете некоторых комментариев, если мне нужно будет привязать одну базу данных (с точки зрения диалекта SQL), это должен быть PostgreSQL

Запросы, которые я хочу написать, имеют форму (конечно, псевдо SQL):

Query Type 1 (Period on Period Change)
=======================================
a). select product_id, ((sd2.sales_amt - sd1.sales_amt)/sd1.sales_amt) as week_on_week_change from sales_data sd1, sales_data sd2, date_dimension dd where {SOME CRITERIA)

b). select product_id, ((sd2.sales_amt - sd1.sales_amt)/sd1.sales_amt) as month_on_month_change from sales_data sd1, sales_data sd2, date_dimension dd where {SOME CRITERIA)


Query Type 2  (Change in Period on Period Change)
=================================================
a). select product_id, ((a2.week_on_week_change - a1.week_on_week_change)/a1.week_on_week_change) as change_on_week_on_week_change from 
(select product_id, ((sd2.sales_amt - sd1.sales_amt)/sd1.sales_amt) as week_on_week_change from sales_data sd1, sales_data sd2, date_dimension dd where {SOME CRITERIA)
as a1), 
(select product_id, ((sd2.sales_amt - sd1.sales_amt)/sd1.sales_amt) as week_on_week_change from sales_data sd1, sales_data sd2, date_dimension dd where {SOME CRITERIA) as a2)
WHERE {SOME OTHER CRITERIA}

1 Ответ

2 голосов
/ 26 мая 2010

PostgreSQL 8.4 имеет оконные функции, которые могут помочь рассчитать изменение периода на период без необходимости объединения таблицы против себя.

Например, чтобы получить сравнение за неделю:

create view week_on_week_sales as
select week_part,
       week_sales,
       lag(week_sales, 1) over(order by week_part) as previous_week_sales
from (select week_part,
             sum(sales_amt) as week_sales
      from sales_data
           join date_dimension 
                on sales_data.sales_time = date_dimension.datestamp
      group by date_dimension.week_part) x
order by week_part

Аналогично, чтобы получить вторую производную, вы можете заключить ее в следующий подзапрос:

select week_part,
       week_sales - previous_week_sales as change,
       week_sales - previous_week_sales
              - lag(week_sales - previous_week_sales, 1) over(order by week_part)
              as change_in_change
from week_on_week_sales

Синтаксис окна стандартизирован в SQL: 2003 , я полагаю. Однако реализации не все одинаковы. Например, SQL Server, в частности, не реализует функции LEAD () и LAG (). Я проверял это на Postgresql 8.4. Oracle поддерживает аналогичные функции (и Postgresql обычно следует за Oracle), и я считаю, что DB2 также поддерживает эти запросы, хотя точный синтаксис может отличаться. Другие

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...