You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何直观理解数据仓库中的Time Dimension?维度建模新手求助

如何为班次事实表创建时间维度表(Oracle/SQL Developer)

嘿,作为维度建模的新手,这种困惑太正常啦!别担心,咱们一步步来搞定这个时间维度表的创建——它可是维度建模里最基础也最实用的维度之一,能帮你轻松按日期、月份、季度等维度分析班次数据。

首先,先明确咱们的目标:创建一个包含丰富时间属性的维度表,和你的事实表通过shift_date关联起来,方便后续的分析查询。因为你用的是SQL Developer,咱们就基于Oracle语法来写脚本。

第一步:确定日期范围

你的示例数据从2011年1月开始,咱们先设定一个足够覆盖你业务所有班次日期的范围(比如从2011年1月1日到未来几年,你可以根据实际情况调整)。

第二步:创建时间维度表并插入数据

直接运行下面的SQL脚本就行,我会给你解释每个部分的作用:

-- 创建时间维度表
CREATE TABLE time_dimension (
    time_sk NUMBER PRIMARY KEY, -- 代理键,维度表的唯一标识
    shift_date DATE NOT NULL UNIQUE, -- 和事实表关联的自然键
    year NUMBER(4) NOT NULL, -- 年份,比如2011
    month_number NUMBER(2) NOT NULL, -- 月份数字,1-12
    month_name VARCHAR2(20) NOT NULL, -- 月份名称,比如January
    day_of_month NUMBER(2) NOT NULL, -- 当月第几天,1-31
    day_of_week NUMBER(1) NOT NULL, -- 当周第几天(1=周日,2=周一...7=周六,可调整)
    day_name VARCHAR2(20) NOT NULL, -- 星期名称,比如Saturday
    quarter NUMBER(1) NOT NULL, -- 季度,1-4
    is_weekend VARCHAR2(3) NOT NULL -- 是否周末,YES/NO
);

-- 插入数据,生成日期范围的所有时间属性
INSERT INTO time_dimension (time_sk, shift_date, year, month_number, month_name, day_of_month, day_of_week, day_name, quarter, is_weekend)
SELECT
    ROWNUM AS time_sk, -- 自动生成递增的代理键
    start_date + LEVEL - 1 AS shift_date,
    EXTRACT(YEAR FROM start_date + LEVEL - 1) AS year,
    EXTRACT(MONTH FROM start_date + LEVEL - 1) AS month_number,
    TO_CHAR(start_date + LEVEL - 1, 'Month') AS month_name,
    EXTRACT(DAY FROM start_date + LEVEL - 1) AS day_of_month,
    TO_CHAR(start_date + LEVEL - 1, 'D') AS day_of_week,
    TO_CHAR(start_date + LEVEL - 1, 'Day') AS day_name,
    CEIL(EXTRACT(MONTH FROM start_date + LEVEL - 1)/3) AS quarter,
    CASE WHEN TO_CHAR(start_date + LEVEL - 1, 'D') IN ('1', '7') THEN 'YES' ELSE 'NO' END AS is_weekend
FROM (
    SELECT TO_DATE('01-01-2011', 'DD-MM-YYYY') AS start_date,
           TO_DATE('31-12-2025', 'DD-MM-YYYY') AS end_date -- 这里调整结束日期
    FROM dual
)
CONNECT BY LEVEL <= end_date - start_date + 1;

-- 提交事务
COMMIT;

第三步:理解脚本细节

  • time_sk:维度表的代理键,用ROWNUM自动生成,避免依赖业务日期的变化,是维度建模的最佳实践。
  • 各种时间属性:比如yearmonth_nameis_weekend这些,都是为了后续分析方便——比如你想统计每个月的filled班次总工时,或者周末的取消班次数量,直接用这些属性过滤就行。
  • 日期范围:你可以修改子查询里的start_dateend_date,覆盖你业务需要的所有日期区间。

第四步:关联事实表和时间维度表

之后你查询的时候,就可以通过fact_table.shift_date = time_dimension.shift_date来关联,比如:

SELECT td.month_name, td.year, SUM(f.Hrs_worked) AS total_hours
FROM fact_table f
JOIN time_dimension td ON f.shift_date = td.shift_date
WHERE f.shift_status = 'Filled'
GROUP BY td.year, td.month_name
ORDER BY td.year, td.month_number;

如果还有其他需求(比如需要财年、节假日标记等),可以随时给时间维度表加字段哦!

内容的提问来源于stack exchange,提问作者dwalker

火山引擎 最新活动