sql - 如何使用 ANSI SQL 为一个简单的数据仓库编写这两个查询?

标签 sql data-warehouse ansi-sql

我正在编写一个简单的数据仓库,它允许我查询表以观察数据的周期性(比如每周)变化,以及数据变化的变化(例如每周销售额的每周变化)。

为了简单起见,我将展示我在这里使用的表格的非常简化(几乎是微不足道的)版本。销售数据表是一个 View ,结构如下:

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. 返回指定时间段内week on week sales_amt 的变化。例如,今天的销售额与 N 天前的销售额之间的变化 - 其中 N 是一个正整数(在本例中 N == 7)。

  2. 返回指定期间sales_amt 的变化。在 (1) 中。我们计算了每周的变化。现在我们想知道这种变化与 上周计算的(每周)变化。

然而,我被困在这一点上,因为 SQL 是我最弱的技能。如果 SQL 大师能解释我如何以与 DB 无关的方式(即使用 ANSI SQL)编写这些查询,我将不胜感激。

最佳答案

如上面评论中所述,我可能不了解您的模型 - 所以这是一个简单的入门。

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是dimDate中的一列,varchar(8),例如'2010-w03',Year也是dimDate中的整数列。

不确定这是否接近您所寻找的,但可能是一个开始。

编辑

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 ;

关于sql - 如何使用 ANSI SQL 为一个简单的数据仓库编写这两个查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2910414/

相关文章:

sql - SQL 标准与 T-SQL 扩展的性能

sql - 使用具有相同参数的 select 或 update 时受影响的行数不同 - PostgreSQL

php - 如何防止 PHP 中的 SQL 注入(inject)?

sql-server - Azure SQL 数据仓库是否有分割字符串的方法?

sql - sql server中列中新值的唯一键约束

join - 使用 ETL 中的表连接更改数据捕获

data-warehouse - 数据阶段并行作业导出选项

mysql - MYSQL LIMIT 关键字是否有 ANSI SQL 替代品?

sql - 如何组合这些查询?

MySQL - 递归重新排序算法/具有变量增量的更新