3

私は単純なデータ ウェアハウスを作成しており、テーブルにクエリを実行してデータの定期的な (たとえば毎週の) 変化と、データの変化の変化 (たとえば、毎週の売上高の週ごとの変化) を観察できます。

簡単にするために、ここで使用しているテーブルの非常に単純化された (ほとんど自明化された) バージョンを提示します。売上データ テーブルはビューであり、次の構造を持っています。

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

この質問の目的のために。product_id、sales_person_id などの他のフィールドは、この質問と直接関係がないため省略しています。AFAICT、クエリで使用される唯一のフィールドは、sales_time フィールドと sales_amt フィールドです (私が間違っていない限り)。

次の構造の日付ディメンション テーブルもあります。

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, 
);

日付をレポート範囲に分割します。

次のことができるクエリを作成する必要があります。

  1. 指定された期間の週 sales_amt の週の変化を返します。たとえば、今日の売上と N 日前の売上の変化 - N は正の整数 (この場合は N == 7) です。

  2. 指定された期間の sales_amt の変化の変化を返します。(1)の場合。週ごとの変化を計算しました。ここで、その変化が、先週計算された (週ごとの) 変化とどのように異なるかを知りたいと考えています。

ただし、SQL は私の最も弱いスキルであるため、この時点で立ち往生しています。SQL マスターが、これらのクエリを DB にとらわれない方法で (つまり、ANSI SQL を使用して) 記述する方法を説明してくれるとありがたいです。

4

2 に答える 2

5

上記のコメントで述べたように、私はおそらくあなたのモデルを理解していません。

dim4_model_01_1

2010 年の暦年の毎週の売上が必要な場合

select 
    CalendarYearWeek
  , sum(SalesAmount)
from factSales as f
join dimDate as d on d.DateKey = f.DateKey
where Year = 2010
group by CalendarYearWeek

CalendarYearWeek'2010-w03' などの varchar(8) は、dimDate のYear整数列でもあります。

これがあなたが探していたものに近いかどうかはわかりませんが、出発点かもしれません.

編集

dimDateには次の列もあります。

WeekNumberInEpoch、整数 -- 過去のあるエポック日付から開始して増加します。同じ週内の dimDate のすべての行は、同じ WeekNumberInEpoch を持ちます。

DayOfWeek、varchar(10) -- '日曜日'、'月曜日'、...

DayNumberInWeek、整数 -- 1 ~ 7

これは CTE を使用し、最新の PostgreSQL、SQL Server、Oracle、DB2 で動作するはずです。他の場合は、CTE (q_00) をサブクエリにパッケージ化できます。

-- for week to previous week
with
q_00 as (
    select
        WeekNumberInEpoch
      , sum(SalesAmount) as Amount
    from factSale as f
    join dimDate  as d on d.DateKey = f.DateKey
    where CalendarYear = 2010
    group by WeekNumberInEpoch
)
select
    a.WeekNumberInEpoch
  , a.Amount as ThisWeekSales
  , b.Amount as LastWeekSales
  , a.Amount - b.Amount as Difference
from q_00 as a
join q_00 as b on b.WeekNumberInEpoch = a.WeekNumberInEpoch - 1
order by a.WeekNumberInEpoch desc ;


-- for day of week to day of previous week 
-- monday to monday, tuesday to tuesday, ...
with
q_00 as (
    select
        WeekNumberInEpoch
      , DayOfWeek  
      , sum(SalesAmount) as Amount
    from factSale as f
    join dimDate  as d on d.DateKey = f.DateKey
    where CalendarYear = 2010
    group by WeekNumberInEpoch, DayOfWeek
)
select
    a.WeekNumberInEpoch
  , a.DayOfWeek  
  , a.Amount as ThisWeekSales
  , b.Amount as LastWeekSales
  , a.Amount - b.Amount as Difference
from q_00 as a
join q_00 as b on (b.WeekNumberInEpoch = a.WeekNumberInEpoch - 1
                   and b.DayOfWeek = a.DayOfWeek)
order by a.WeekNumberInEpoch desc, a.DayOfWeek ;



-- Sliding by day and day difference (= 7)
with
q_00 as (
    select
        DayNumberInEpoch
      , FullDate
      , DayOfWeek
      , sum(SalesAmount) as Amount
    from factSale as f
    join dimDate as d on d.DateKey = f.DateKey
    where CalendarYear = 2010
    group by DayNumberInEpoch, FullDate, DayOfWeek
)
select
    a.FullDate  as ThisDay
  , a.DayOfWeek as ThisDayName
  , a.Amount    as ThisDaySales
  , b.FullDate  as PreviousPeriodDay
  , b.DayOfWeek as PreviousDayName
  , b.Amount    as PreviousPeriodDaySales
  , a.Amount - b.Amount as Difference
from q_00 as a
join q_00 as b on b.DayNumberInEpoch = a.DayNumberInEpoch - 7
order by a.FullDate desc ;
于 2010-05-26T12:34:26.093 に答える
3

「時間」(行ごとに 1 日、繰り返し期間 (日、週、月、四半期) に関する情報を含む) 用に別のディメンション テーブルを作成して、そのタイプの情報を簡単に結合/選択できるようにすることをお勧めします。

(1.) と (2.) のクエリは、そのように作成できます。

はい、ほとんどの SQL 方言では、時刻/日付関数を使用してその情報を推測できます..しかし、それらは遅く (-er)、ディメンション テーブルを使用するよりも複雑です..

于 2010-05-26T06:14:54.320 に答える