在前后端开发联调前 的提交20260223

This commit is contained in:
Neo
2026-02-23 23:02:20 +08:00
parent 254ccb1e77
commit fafc95e64c
1142 changed files with 10366960 additions and 36957 deletions

View File

@@ -1,21 +1,55 @@
# db/
# db/ — 数据库资产目录
## 作用说明
## 当前状态2026-02-22 基线重置后)
数据库资产目录,集中管理所有数据库的 DDL、迁移脚本和种子数据。每个数据库实例对应一个子目录
完整 DDL 基线已迁移至 `docs/database/ddl/`(按 schema 分文件,从测试库自动导出)
本目录保留运行时资产种子数据、FDW 配置、建库脚本),历史文件已归档。
## 内部结构
## 目录结构
- `etl_feiqiu/` — ETL 数据库(六层 schemameta/ods/dwd/core/dws/app
- `schemas/` — DDL 定义(每个 schema 一个文件)
- `migrations/` — 迁移脚本(日期前缀命名)
- `seeds/` — 种子数据
- `zqyy_app/` — 业务应用数据库(用户/权限/任务/审批
- `schemas/` / `migrations/` / `seeds/`
- `fdw/` — PostgreSQL FDW 跨库映射配置
```
db/
├── etl_feiqiu/
├── schemas/ — 已清空DDL 基线见 docs/database/ddl/etl_feiqiu__*.sql
│ ├── migrations/ — 已归档(全部变更已吸收进新 DDL 基线
├── seeds/ — 种子数据(运行时需要)
│ │ ├── seed_ods_tasks.sql
│ │ ├── seed_scheduler_tasks.sql
│ │ ├── seed_dws_config.sql
│ │ └── seed_index_parameters.sql
│ └── scripts/
│ └── create_test_db.sql
├── zqyy_app/
│ ├── schemas/ — 已清空
│ ├── migrations/ — 已归档
│ ├── seeds/
│ │ └── admin_web_seed.sql
│ └── scripts/
│ └── create_test_db.sql
├── fdw/ — FDW 跨库映射配置(正式 + 测试 + 反向)
│ ├── setup_fdw.sql
│ ├── setup_fdw_test.sql
│ ├── setup_fdw_reverse.sql
│ └── setup_fdw_reverse_test.sql
└── _archived/ — 归档(旧 DDL + 迁移脚本,仅供历史参考)
└── ddl_baseline_2026-02-22/
```
## Roadmap
## DDL 基线
- FDW 演进:当前为单机 localhost 映射,未来支持跨主机远程 FDW 配置
- 引入 schema diff 工具,自动检测生产与测试库结构偏差
- 考虑 FDW 性能监控与查询下推优化
新建库或 schema diff 请使用:
- `docs/database/ddl/etl_feiqiu__meta.sql`
- `docs/database/ddl/etl_feiqiu__ods.sql`
- `docs/database/ddl/etl_feiqiu__dwd.sql`
- `docs/database/ddl/etl_feiqiu__core.sql`
- `docs/database/ddl/etl_feiqiu__dws.sql`
- `docs/database/ddl/etl_feiqiu__app.sql`(仅视图)
- `docs/database/ddl/zqyy_app__public.sql`
- `docs/database/ddl/fdw.sql`
重新生成:`python scripts/ops/gen_consolidated_ddl.py`
## 未来迁移
归档后,新的迁移脚本仍放 `migrations/`,文件名格式 `YYYY-MM-DD__描述.sql`
每次迁移执行后,建议重新运行 DDL 生成脚本刷新基线。

View File

@@ -0,0 +1,67 @@
-- 迁移:为 dwd_assistant_service_log_ex 新增 operator_id、operator_name 两列
-- 关联需求dataflow-field-completion Requirements 2.1, 2.2
-- 日期2026-02-20
BEGIN;
-- 1. 新增列
ALTER TABLE dwd.dwd_assistant_service_log_ex
ADD COLUMN IF NOT EXISTS operator_id BIGINT;
ALTER TABLE dwd.dwd_assistant_service_log_ex
ADD COLUMN IF NOT EXISTS operator_name TEXT;
-- 2. 列注释
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.operator_id IS
'【说明】操作员 ID录入/结算这条助教服务的员工。 【ODS来源】assistant_service_records - operator_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - operator_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.operator_name IS
'【说明】操作员姓名(带职位前缀),与 operator_id 一起使用,便于直接阅读。 【ODS来源】assistant_service_records - operator_name。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - operator_name。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE dwd.dwd_assistant_service_log_ex DROP COLUMN IF EXISTS operator_id;
-- ALTER TABLE dwd.dwd_assistant_service_log_ex DROP COLUMN IF EXISTS operator_name;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 2 个新列均已创建且类型正确
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dwd_assistant_service_log_ex'
-- AND column_name IN ('operator_id', 'operator_name')
-- ORDER BY column_name;
-- 2. 确认列注释已添加
-- SELECT column_name,
-- col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- attnum
-- ) AS comment
-- FROM pg_attribute
-- WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
-- AND attname IN ('operator_id', 'operator_name');
-- 3. 确认 ODS 源表中同名列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'assistant_service_records'
-- AND column_name IN ('operator_id', 'operator_name')
-- ORDER BY column_name;
-- 4. 重新加载后抽样验证新列有数据
-- SELECT operator_id, operator_name
-- FROM dwd.dwd_assistant_service_log_ex
-- WHERE operator_id IS NOT NULL
-- LIMIT 10;

View File

@@ -0,0 +1,14 @@
-- 迁移:为 dwd_assistant_trash_event_ex 新增 assistant_no_int 列
-- 背景:主表 assistant_no (VARCHAR) 映射自 ODS assistanton存储的是数字编号的字符串形式。
-- 新增 INTEGER 类型列便于数值比较和关联助教档案。
-- 日期2026-02-20
BEGIN;
ALTER TABLE dwd.dwd_assistant_trash_event_ex
ADD COLUMN IF NOT EXISTS assistant_no_int INTEGER;
COMMENT ON COLUMN dwd.dwd_assistant_trash_event_ex.assistant_no_int IS
'【说明】助教编号(整数形式),与主表 assistant_noVARCHAR同源但类型不同便于数值比较和关联。 【示例】6。 【ODS来源】assistant_cancellation_records - assistanton。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantOn。';
COMMIT;

View File

@@ -0,0 +1,71 @@
-- 迁移:为 dwd.dim_assistant_ex 新增 4 个字段
-- 来源assistant_accounts_master ODS 表中已有同名列,直接映射
-- 关联需求dataflow-field-completion Requirements 1.1, 1.2, 1.3
BEGIN;
-- 1. 新增列
ALTER TABLE dwd.dim_assistant_ex ADD COLUMN IF NOT EXISTS system_role_id BIGINT;
ALTER TABLE dwd.dim_assistant_ex ADD COLUMN IF NOT EXISTS job_num TEXT;
ALTER TABLE dwd.dim_assistant_ex ADD COLUMN IF NOT EXISTS cx_unit_price NUMERIC(18,2);
ALTER TABLE dwd.dim_assistant_ex ADD COLUMN IF NOT EXISTS pd_unit_price NUMERIC(18,2);
-- 2. 添加列注释
COMMENT ON COLUMN dwd.dim_assistant_ex.system_role_id IS
'【说明】系统角色 ID标识助教在系统中的角色类型。 【ODS来源】assistant_accounts_master - system_role_id。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - system_role_id。';
COMMENT ON COLUMN dwd.dim_assistant_ex.job_num IS
'【说明】工号,助教的内部编号标识。 【ODS来源】assistant_accounts_master - job_num。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - job_num。';
COMMENT ON COLUMN dwd.dim_assistant_ex.cx_unit_price IS
'【说明】促销单价(元),助教提供促销服务时的计费单价。 【ODS来源】assistant_accounts_master - cx_unit_price。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - cx_unit_price。';
COMMENT ON COLUMN dwd.dim_assistant_ex.pd_unit_price IS
'【说明】陪打单价(元),助教提供陪打服务时的计费单价。 【ODS来源】assistant_accounts_master - pd_unit_price。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - pd_unit_price。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE dwd.dim_assistant_ex DROP COLUMN IF EXISTS system_role_id;
-- ALTER TABLE dwd.dim_assistant_ex DROP COLUMN IF EXISTS job_num;
-- ALTER TABLE dwd.dim_assistant_ex DROP COLUMN IF EXISTS cx_unit_price;
-- ALTER TABLE dwd.dim_assistant_ex DROP COLUMN IF EXISTS pd_unit_price;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 4 个新列均已创建且类型正确
-- SELECT column_name, data_type, numeric_precision, numeric_scale
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dim_assistant_ex'
-- AND column_name IN ('system_role_id', 'job_num', 'cx_unit_price', 'pd_unit_price')
-- ORDER BY column_name;
-- 2. 确认列注释已添加
-- SELECT column_name,
-- col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dim_assistant_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- attnum
-- ) AS comment
-- FROM pg_attribute
-- WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dim_assistant_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
-- AND attname IN ('system_role_id', 'job_num', 'cx_unit_price', 'pd_unit_price');
-- 3. 确认 ODS 源表中同名列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'assistant_accounts_master'
-- AND column_name IN ('system_role_id', 'job_num', 'cx_unit_price', 'pd_unit_price')
-- ORDER BY column_name;
-- 4. 重新加载后抽样验证新列有数据
-- SELECT system_role_id, job_num, cx_unit_price, pd_unit_price
-- FROM dwd.dim_assistant_ex
-- WHERE scd2_is_current = 1
-- LIMIT 10;

View File

@@ -0,0 +1,49 @@
-- 迁移:为 dwd.dim_store_goods_ex 新增 batch_stock_quantity 列
-- 日期2026-02-20
-- 关联需求dataflow-field-completionNEW_FIELDS 中定义但缺少迁移脚本)
-- 说明:批次库存数量,来源 ODS store_goods_master.batch_stock_quantity
BEGIN;
ALTER TABLE dwd.dim_store_goods_ex
ADD COLUMN IF NOT EXISTS batch_stock_quantity NUMERIC;
COMMENT ON COLUMN dwd.dim_store_goods_ex.batch_stock_quantity IS
'【说明】批次库存数量区别于当前库存stock和主表的 batch_stock_qty。 【ODS来源】store_goods_master - batch_stock_quantity。 【JSON字段】store_goods_master.json - data.orderGoodsList - batchStockQuantity。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE dwd.dim_store_goods_ex DROP COLUMN IF EXISTS batch_stock_quantity;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认新列已创建且类型正确
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dim_store_goods_ex'
-- AND column_name = 'batch_stock_quantity';
-- 2. 确认列注释已添加
-- SELECT col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dim_store_goods_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- (SELECT attnum FROM pg_attribute
-- WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dim_store_goods_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
-- AND attname = 'batch_stock_quantity')
-- ) AS batch_stock_quantity_comment;
-- 3. 确认 ODS 源表中同名列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'store_goods_master'
-- AND column_name = 'batch_stock_quantity';

View File

@@ -0,0 +1,129 @@
-- 迁移:为 dwd.dim_table_ex 新增 14 个字段
-- 来源site_tables_master ODS 表中已有同名列(部分驼峰式在 PG 中已小写化)
-- 关联需求dataflow-field-completion Requirements 9.1, 9.2
BEGIN;
-- 1. 新增列
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS create_time TIMESTAMPTZ;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS light_status INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS tablestatusname TEXT;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS sitename TEXT;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS applet_qr_code_url TEXT;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS audit_status INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS charge_free INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS delay_lights_time INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS is_rest_area INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS only_allow_groupon INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS order_delay_time INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS self_table INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS temporary_light_second INTEGER;
ALTER TABLE dwd.dim_table_ex ADD COLUMN IF NOT EXISTS virtual_table INTEGER;
-- 2. 添加列注释
COMMENT ON COLUMN dwd.dim_table_ex.create_time IS
'【说明】台桌配置的创建时间或最近一次创建/复制时间。 【示例】2025-07-15 17:52:54。 【ODS来源】site_tables_master - create_time。 【JSON字段】site_tables_master.json - data.siteTables - create_time。';
COMMENT ON COLUMN dwd.dim_table_ex.light_status IS
'【说明】台灯状态枚举(如 2=已开灯),用于标识台桌灯光当前状态。 【示例】2。 【ODS来源】site_tables_master - light_status。 【JSON字段】site_tables_master.json - data.siteTables - light_status。';
COMMENT ON COLUMN dwd.dim_table_ex.tablestatusname IS
'【说明】台桌状态中文名称(如"空闲中""使用中"),仅展示用途。 【示例】空闲中。 【ODS来源】site_tables_master - tablestatusname。 【JSON字段】site_tables_master.json - data.siteTables - tableStatusName。';
COMMENT ON COLUMN dwd.dim_table_ex.sitename IS
'【说明】门店名称快照,冗余字段,配合 site_id 使用。 【示例】朗朗桌球。 【ODS来源】site_tables_master - sitename。 【JSON字段】site_tables_master.json - data.siteTables - siteName。';
COMMENT ON COLUMN dwd.dim_table_ex.applet_qr_code_url IS
'【说明】小程序二维码 URL用于扫码开台等场景。 【ODS来源】site_tables_master - appletQrCodeUrl。 【JSON字段】site_tables_master.json - data.siteTables - appletQrCodeUrl。';
COMMENT ON COLUMN dwd.dim_table_ex.audit_status IS
'【说明】审核状态枚举(当前全部为 2含义待确认。 【示例】2。 【ODS来源】site_tables_master - audit_status。 【JSON字段】site_tables_master.json - data.siteTables - audit_status。';
COMMENT ON COLUMN dwd.dim_table_ex.charge_free IS
'【说明】是否免费台0=收费1=免费),当前全部为 0。 【示例】0。 【ODS来源】site_tables_master - charge_free。 【JSON字段】site_tables_master.json - data.siteTables - charge_free。';
COMMENT ON COLUMN dwd.dim_table_ex.delay_lights_time IS
'【说明】台灯熄灭延迟时间(单位秒或分钟),结账后延时关灯。 【示例】0。 【ODS来源】site_tables_master - delay_lights_time。 【JSON字段】site_tables_master.json - data.siteTables - delay_lights_time。';
COMMENT ON COLUMN dwd.dim_table_ex.is_rest_area IS
'【说明】是否休息区台桌0=否1=是),当前全部为 0。 【示例】0。 【ODS来源】site_tables_master - is_rest_area。 【JSON字段】site_tables_master.json - data.siteTables - is_rest_area。';
COMMENT ON COLUMN dwd.dim_table_ex.only_allow_groupon IS
'【说明】是否仅允许团购开台0/1/2 枚举)。 【示例】2。 【ODS来源】site_tables_master - only_allow_groupon。 【JSON字段】site_tables_master.json - data.siteTables - only_allow_groupon。';
COMMENT ON COLUMN dwd.dim_table_ex.order_delay_time IS
'【说明】订单自动延时时长(到点后自动延长继续计费的时间)。 【示例】0。 【ODS来源】site_tables_master - order_delay_time。 【JSON字段】site_tables_master.json - data.siteTables - order_delay_time。';
COMMENT ON COLUMN dwd.dim_table_ex.self_table IS
'【说明】是否自有台桌1=自有),当前全部为 1。 【示例】1。 【ODS来源】site_tables_master - self_table。 【JSON字段】site_tables_master.json - data.siteTables - self_table。';
COMMENT ON COLUMN dwd.dim_table_ex.temporary_light_second IS
'【说明】临时开灯秒数,用于短时照明场景。 【示例】0。 【ODS来源】site_tables_master - temporary_light_second。 【JSON字段】site_tables_master.json - data.siteTables - temporary_light_second。';
COMMENT ON COLUMN dwd.dim_table_ex.virtual_table IS
'【说明】是否虚拟台桌0=实体台1=虚拟台)。 【示例】0。 【ODS来源】site_tables_master - virtual_table。 【JSON字段】site_tables_master.json - data.siteTables - virtual_table。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS create_time;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS light_status;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS tablestatusname;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS sitename;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS applet_qr_code_url;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS audit_status;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS charge_free;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS delay_lights_time;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS is_rest_area;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS only_allow_groupon;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS order_delay_time;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS self_table;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS temporary_light_second;
-- ALTER TABLE dwd.dim_table_ex DROP COLUMN IF EXISTS virtual_table;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 14 个新列均已创建且类型正确
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dim_table_ex'
-- AND column_name IN (
-- 'create_time', 'light_status', 'tablestatusname', 'sitename',
-- 'applet_qr_code_url', 'audit_status', 'charge_free', 'delay_lights_time',
-- 'is_rest_area', 'only_allow_groupon', 'order_delay_time', 'self_table',
-- 'temporary_light_second', 'virtual_table'
-- )
-- ORDER BY column_name;
-- 2. 确认列注释已添加(应返回 14 行)
-- SELECT column_name,
-- col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dim_table_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- attnum
-- ) AS comment
-- FROM pg_attribute
-- WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dim_table_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
-- AND attname IN (
-- 'create_time', 'light_status', 'tablestatusname', 'sitename',
-- 'applet_qr_code_url', 'audit_status', 'charge_free', 'delay_lights_time',
-- 'is_rest_area', 'only_allow_groupon', 'order_delay_time', 'self_table',
-- 'temporary_light_second', 'virtual_table'
-- );
-- 3. 确认 ODS 源表中对应列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'site_tables_master'
-- AND column_name IN (
-- 'create_time', 'light_status', 'tablestatusname', 'sitename',
-- 'appletQrCodeUrl', 'audit_status', 'charge_free', 'delay_lights_time',
-- 'is_rest_area', 'only_allow_groupon', 'order_delay_time', 'self_table',
-- 'temporary_light_second', 'virtual_table'
-- )
-- ORDER BY column_name;
-- 4. 重新加载后抽样验证新列有数据
-- SELECT create_time, light_status, tablestatusname, sitename,
-- applet_qr_code_url, audit_status, charge_free, delay_lights_time,
-- is_rest_area, only_allow_groupon, order_delay_time, self_table,
-- temporary_light_second, virtual_table
-- FROM dwd.dim_table_ex
-- WHERE scd2_is_current = 1
-- LIMIT 10;

View File

@@ -0,0 +1,57 @@
-- 迁移:为 dwd_member_balance_change_ex 新增 relate_id 列
-- 关联需求dataflow-field-completion Requirements 5.1, 5.2
-- 说明relate_id 为关联业务单据 ID指向触发余额变动的业务记录充值单、订单等
-- ODS 源列ods.member_balance_changes.relate_idBIGINT已存在
BEGIN;
-- 新增列
ALTER TABLE dwd.dwd_member_balance_change_ex
ADD COLUMN IF NOT EXISTS relate_id BIGINT;
-- 添加列注释
COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.relate_id IS
'【说明】关联业务单据 ID指向触发本次余额变动的业务记录如充值单、订单、结算单等按 from_type 不同指向不同表。 【示例】2957881518788421。 【ODS来源】member_balance_changes - relate_id。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - relate_id。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE dwd.dwd_member_balance_change_ex DROP COLUMN IF EXISTS relate_id;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认新列已创建且类型正确
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dwd_member_balance_change_ex'
-- AND column_name = 'relate_id';
-- 2. 确认列注释已添加
-- SELECT col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dwd_member_balance_change_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- (SELECT attnum FROM pg_attribute
-- WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dwd_member_balance_change_ex'
-- AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
-- AND attname = 'relate_id')
-- ) AS relate_id_comment;
-- 3. 确认 ODS 源表中同名列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'member_balance_changes'
-- AND column_name = 'relate_id';
-- 4. 重新加载后抽样验证新列有数据
-- SELECT relate_id, balance_change_id
-- FROM dwd.dwd_member_balance_change_ex
-- WHERE relate_id IS NOT NULL
-- LIMIT 10;

View File

@@ -0,0 +1,34 @@
-- 迁移:新建 dwd.dwd_goods_stock_movement 表
-- 日期2026-02-20
-- 原因:为库存变动流水创建 DWD 层明细表,按 create_time 增量加载
-- 关联任务dataflow-field-completion Task 6.2
BEGIN;
CREATE TABLE IF NOT EXISTS dwd.dwd_goods_stock_movement (
site_goods_stock_id BIGINT NOT NULL,
tenant_id BIGINT,
site_id BIGINT,
site_goods_id BIGINT,
goods_name TEXT,
goods_category_id BIGINT,
goods_second_category_id BIGINT,
unit TEXT,
price NUMERIC(18,4),
stock_type INTEGER,
change_num NUMERIC(18,4),
start_num NUMERIC(18,4),
end_num NUMERIC(18,4),
change_num_a NUMERIC(18,4),
start_num_a NUMERIC(18,4),
end_num_a NUMERIC(18,4),
remark TEXT,
operator_name TEXT,
create_time TIMESTAMPTZ,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_stock_id)
);
COMMENT ON TABLE dwd.dwd_goods_stock_movement IS '库存变动流水表事实表。来源ods.goods_stock_movements。按 create_time 增量加载。';
COMMIT;

View File

@@ -0,0 +1,31 @@
-- 迁移:新建 dwd.dwd_goods_stock_summary 表
-- 日期2026-02-20
-- 原因:为库存汇总数据创建 DWD 层明细表,支持按时间窗口增量加载
-- 关联任务dataflow-field-completion Task 6.1
BEGIN;
CREATE TABLE IF NOT EXISTS dwd.dwd_goods_stock_summary (
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC(18,4),
range_end_stock NUMERIC(18,4),
range_in NUMERIC(18,4),
range_out NUMERIC(18,4),
range_sale NUMERIC(18,4),
range_sale_money NUMERIC(18,2),
range_inventory NUMERIC(18,4),
current_stock NUMERIC(18,4),
site_id BIGINT,
tenant_id BIGINT,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_id, fetched_at)
);
COMMENT ON TABLE dwd.dwd_goods_stock_summary IS '库存汇总明细表事实表。来源ods.goods_stock_summary。按时间窗口增量加载。';
COMMIT;

View File

@@ -0,0 +1,147 @@
-- =============================================================================
-- 迁移脚本:创建 DWS 库存汇总表(日/周/月)
-- 日期: 2026-02-20
-- 依赖: dwd.dwd_goods_stock_summary 已存在
-- 说明: 三张表结构相同,仅 stat_period 默认值不同
-- 回滚: 见文件末尾 ROLLBACK 段
-- =============================================================================
BEGIN;
-- -----------------------------------------------------------------------------
-- 1. 日度汇总
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS dws.dws_goods_stock_daily_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'daily',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_daily_summary
IS '库存日度汇总:按门店+日期+商品汇总库存变动';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_date
ON dws.dws_goods_stock_daily_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_goods
ON dws.dws_goods_stock_daily_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_site
ON dws.dws_goods_stock_daily_summary (site_id, stat_date);
-- -----------------------------------------------------------------------------
-- 2. 周度汇总
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS dws.dws_goods_stock_weekly_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'weekly',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_weekly_summary
IS '库存周度汇总:按门店+ISO周+商品汇总库存变动stat_date 为周一日期';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_date
ON dws.dws_goods_stock_weekly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_goods
ON dws.dws_goods_stock_weekly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_site
ON dws.dws_goods_stock_weekly_summary (site_id, stat_date);
-- -----------------------------------------------------------------------------
-- 3. 月度汇总
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS dws.dws_goods_stock_monthly_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'monthly',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_monthly_summary
IS '库存月度汇总:按门店+自然月+商品汇总库存变动stat_date 为月首日期';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_date
ON dws.dws_goods_stock_monthly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_goods
ON dws.dws_goods_stock_monthly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_site
ON dws.dws_goods_stock_monthly_summary (site_id, stat_date);
COMMIT;
-- =============================================================================
-- 验证 SQL
-- =============================================================================
-- 1. 确认三张表已创建
-- SELECT table_name FROM information_schema.tables
-- WHERE table_schema = 'dws' AND table_name LIKE 'dws_goods_stock_%_summary';
--
-- 2. 确认主键约束
-- SELECT conname, conrelid::regclass
-- FROM pg_constraint
-- WHERE conrelid::regclass::text LIKE 'dws.dws_goods_stock_%_summary'
-- AND contype = 'p';
--
-- 3. 确认索引数量(每张表 3 个 + 1 个主键 = 4
-- SELECT indexrelid::regclass, indrelid::regclass
-- FROM pg_index
-- WHERE indrelid::regclass::text LIKE 'dws.dws_goods_stock_%_summary';
-- =============================================================================
-- ROLLBACK回滚脚本
-- =============================================================================
-- DROP TABLE IF EXISTS dws.dws_goods_stock_daily_summary CASCADE;
-- DROP TABLE IF EXISTS dws.dws_goods_stock_weekly_summary CASCADE;
-- DROP TABLE IF EXISTS dws.dws_goods_stock_monthly_summary CASCADE;

View File

@@ -0,0 +1,62 @@
-- ============================================================
-- 迁移脚本:修正 dwd_assistant_service_log.site_assistant_id 映射源
-- 日期2026-02-20
-- 问题site_assistant_id 错误映射自 ODS order_assistant_id订单级助教明细 ID
-- 应映射自 ODS site_assistant_id门店维度助教档案 ID
-- 修正:
-- 1. FACT_MAPPINGS 中 site_assistant_id 的 ODS 源从 order_assistant_id 改为 site_assistant_id
-- 2. order_assistant_id 列已存在于 DWD 表中,由同名列自动映射,无需 DDL 变更
-- 3. 更新 COMMENT 以反映正确的 ODS 来源
-- 后续操作:需重新执行 DWD_LOAD_FROM_ODS 任务以修正历史数据
-- ============================================================
BEGIN;
-- 更新 site_assistant_id 的列注释,修正 ODS 来源说明
COMMENT ON COLUMN dwd.dwd_assistant_service_log.site_assistant_id IS
'【说明】门店维度的助教档案 ID关联 assistant_accounts_master.id。'
' 【示例】2946266869435205。'
' 【ODS来源】assistant_service_records - site_assistant_id。'
' 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - site_assistant_id。';
-- 更新 order_assistant_id 的列注释,明确其为订单级 ID
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_assistant_id IS
'【说明】订单中助教项目明细的内部 ID订单级与 site_assistant_id档案级不同。'
' 【示例】2957788717240005。'
' 【ODS来源】assistant_service_records - order_assistant_id。'
' 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_assistant_id。';
COMMIT;
-- ============================================================
-- 回滚脚本(如需撤销):
-- BEGIN;
-- -- 恢复原始 COMMENT
-- COMMENT ON COLUMN dwd.dwd_assistant_service_log.site_assistant_id IS
-- '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957788717240005。 【ODS来源】assistant_service_records - order_assistant_id。';
-- COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_assistant_id IS
-- '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957788717240005。 【ODS来源】assistant_service_records - order_assistant_id。';
-- COMMIT;
-- ============================================================
-- ============================================================
-- 验证 SQL迁移后执行
--
-- 1. 确认 site_assistant_id 注释已更新
-- SELECT col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- (SELECT attnum FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')) AND attname = 'site_assistant_id')
-- );
--
-- 2. 确认 order_assistant_id 列存在且注释已更新
-- SELECT col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- (SELECT attnum FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dwd_assistant_service_log' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')) AND attname = 'order_assistant_id')
-- );
--
-- 3. 确认重新加载后 site_assistant_id 与 order_assistant_id 值不同(抽样)
-- SELECT site_assistant_id, order_assistant_id,
-- (site_assistant_id = order_assistant_id) AS same
-- FROM dwd.dwd_assistant_service_log
-- LIMIT 20;
-- ============================================================

View File

@@ -0,0 +1,85 @@
-- ============================================================
-- 迁移:修正 dim_store_goods.batch_stock_qty 和
-- dim_store_goods_ex.provisional_total_cost 的列注释
-- 日期2026-02-20
-- 关联需求dataflow-field-completion Requirements 10.3
-- ============================================================
-- 变更说明:
-- 本次仅修正列 COMMENT无 DDL 结构变更(列已存在)。
-- batch_stock_qty 的 ODS 来源从 stock 修正为 batch_stock_quantity
-- provisional_total_cost 的 ODS 来源从 total_purchase_cost 修正为 provisional_total_cost
--
-- 代码侧变更(不在本脚本范围):
-- dwd_load_task.py FACT_MAPPINGS 已同步修正
-- 修正后需重新执行 DWD_LOAD_FROM_ODS 以回填历史数据
-- ============================================================
BEGIN;
-- 1. 修正 batch_stock_qty 注释ODS 来源 stock → batch_stock_quantity
COMMENT ON COLUMN dwd.dim_store_goods.batch_stock_qty IS
'【说明】批次库存数量区别于当前库存stock。 【示例】18。 【ODS来源】store_goods_master - batch_stock_quantity。 【JSON字段】store_goods_master.json - data.orderGoodsList - batchStockQuantity。';
-- 2. 修正 provisional_total_cost 注释ODS 来源 total_purchase_cost → provisional_total_cost
COMMENT ON COLUMN dwd.dim_store_goods_ex.provisional_total_cost IS
'【说明】暂估总成本区别于实际采购成本total_purchase_cost。 【示例】0.0。 【ODS来源】store_goods_master - provisional_total_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - provisionalTotalCost。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- COMMENT ON COLUMN dwd.dim_store_goods.batch_stock_qty IS
-- '【说明】数量/时长字段,用于统计与计量。 【示例】18数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - stock。';
-- COMMENT ON COLUMN dwd.dim_store_goods_ex.provisional_total_cost IS
-- '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - total_purchase_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_purchase_cost。';
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 batch_stock_qty 注释已更新为 batch_stock_quantity
SELECT col_description(
(SELECT oid FROM pg_class WHERE relname = 'dim_store_goods'
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
(SELECT attnum FROM pg_attribute
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dim_store_goods'
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
AND attname = 'batch_stock_qty')
) AS batch_stock_qty_comment;
-- 预期:包含 'batch_stock_quantity',不包含 '- stock。'
-- 2. 确认 provisional_total_cost 注释已更新为 provisional_total_cost
SELECT col_description(
(SELECT oid FROM pg_class WHERE relname = 'dim_store_goods_ex'
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
(SELECT attnum FROM pg_attribute
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'dim_store_goods_ex'
AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd'))
AND attname = 'provisional_total_cost')
) AS provisional_total_cost_comment;
-- 预期:包含 'provisional_total_cost',不包含 'total_purchase_cost'
-- 3. 确认两列均存在且类型未变
SELECT column_name, data_type, numeric_precision, numeric_scale
FROM information_schema.columns
WHERE table_schema = 'dwd'
AND (
(table_name = 'dim_store_goods' AND column_name = 'batch_stock_qty')
OR
(table_name = 'dim_store_goods_ex' AND column_name = 'provisional_total_cost')
)
ORDER BY table_name, column_name;
-- 预期batch_stock_qty → integer; provisional_total_cost → numeric(18,2)
-- 4. 重新加载后抽样验证 batch_stock_qty 来自 batch_stock_quantity非 stock
-- SELECT g.batch_stock_qty AS dwd_val,
-- o.batch_stock_quantity AS ods_batch,
-- o.stock AS ods_stock
-- FROM dwd.dim_store_goods g
-- JOIN (SELECT DISTINCT ON (id) * FROM ods.store_goods_master ORDER BY id, fetched_at DESC) o
-- ON g.site_goods_id = o.id
-- WHERE o.batch_stock_quantity IS DISTINCT FROM o.stock
-- LIMIT 20;

View File

@@ -0,0 +1,79 @@
-- ============================================================
-- 迁移脚本:修正 dwd_store_goods_sale.discount_price 列名误导
-- 日期2026-02-20
-- 问题DWD discount_price 实际映射自 ODS discount_money折扣金额
-- 而非 ODS discount_price折后单价列名存在语义误导。
-- 修正:
-- 1. 将 DWD 列 discount_price 重命名为 discount_money反映真实语义折扣金额
-- 2. 新增 DWD 列 discount_pricenumeric映射 ODS discount_price折后单价
-- 3. 更新 COMMENT 以反映正确的语义和 ODS 来源
-- 后续操作:需重新执行 DWD_LOAD_FROM_ODS 任务以填充新 discount_price 列
-- ============================================================
BEGIN;
-- 步骤 1将现有 discount_price 列重命名为 discount_money
ALTER TABLE dwd.dwd_store_goods_sale
RENAME COLUMN discount_price TO discount_money;
-- 步骤 2新增 discount_price 列(折后单价)
ALTER TABLE dwd.dwd_store_goods_sale
ADD COLUMN discount_price NUMERIC(18,2);
-- 步骤 3更新列注释
COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_money IS
'【说明】折扣金额,即原价被减免的金额部分。'
' 【示例】0.0。'
' 【ODS来源】store_goods_sales_records - discount_money。'
' 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_price IS
'【说明】折后单价(元/单位),即应用折扣后的商品单价。'
' 【示例】5.00。'
' 【ODS来源】store_goods_sales_records - discount_price。'
' 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_price。';
COMMIT;
-- ============================================================
-- 回滚脚本(如需撤销):
-- BEGIN;
-- ALTER TABLE dwd.dwd_store_goods_sale DROP COLUMN IF EXISTS discount_price;
-- ALTER TABLE dwd.dwd_store_goods_sale RENAME COLUMN discount_money TO discount_price;
-- COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_price IS
-- '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - discount_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
-- COMMIT;
-- ============================================================
-- ============================================================
-- 验证 SQL迁移后执行
--
-- 1. 确认 discount_money 列存在且注释正确
-- SELECT column_name, data_type, numeric_precision, numeric_scale
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dwd_store_goods_sale'
-- AND column_name = 'discount_money';
--
-- 2. 确认 discount_price 列已新增
-- SELECT column_name, data_type, numeric_precision, numeric_scale
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dwd_store_goods_sale'
-- AND column_name = 'discount_price';
--
-- 3. 确认两列均存在(应返回 2 行)
-- SELECT column_name
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dwd_store_goods_sale'
-- AND column_name IN ('discount_money', 'discount_price')
-- ORDER BY column_name;
--
-- 4. 重新加载后抽样验证 discount_money 与 discount_price 值不同
-- SELECT discount_money, discount_price,
-- (discount_money = discount_price) AS same
-- FROM dwd.dwd_store_goods_sale
-- WHERE discount_price IS NOT NULL
-- LIMIT 20;
-- ============================================================

View File

@@ -0,0 +1,8 @@
-- 移除 settlement_ticket_details 表和索引
-- 该表已从 ETL 流程中彻底移除,不再使用
DROP INDEX IF EXISTS ods.idx_ods_settlement_ticket_details_latest;
DROP TABLE IF EXISTS ods.settlement_ticket_details;
-- 移除 meta.ods_task_registry 中的任务注册
DELETE FROM meta.ods_task_registry WHERE task_code = 'ODS_SETTLEMENT_TICKET';

View File

@@ -0,0 +1,87 @@
-- 迁移:新增 time_slot_sale 字段 + 合并 commodity_code 为数组类型
-- 日期2026-02-21
-- 关联需求dataflow 字段差异修复time_slot_sale 未映射 + commoditycode 合并)
--
-- 变更 1: ods.store_goods_master 新增 time_slot_saleAPI 返回但 ODS 未收录)
-- 变更 2: dwd.dim_store_goods_ex 新增 time_slot_saleODS→DWD 传递)
-- 变更 3: dwd.dim_tenant_goods_ex.commodity_code_list 改为 TEXT[](支持多编码数组)
BEGIN;
-- ============================================================
-- 变更 1: ODS 层 — store_goods_master 新增 time_slot_sale
-- ============================================================
ALTER TABLE ods.store_goods_master
ADD COLUMN IF NOT EXISTS time_slot_sale INTEGER;
COMMENT ON COLUMN ods.store_goods_master.time_slot_sale IS
'【说明】分时段销售标记API 返回值,当前观测全部为 2。 【示例】2。 【JSON字段】store_goods_master.json - data.orderGoodsList - time_slot_sale。';
-- ============================================================
-- 变更 2: DWD 层 — dim_store_goods_ex 新增 time_slot_sale
-- ============================================================
ALTER TABLE dwd.dim_store_goods_ex
ADD COLUMN IF NOT EXISTS time_slot_sale INTEGER;
COMMENT ON COLUMN dwd.dim_store_goods_ex.time_slot_sale IS
'【说明】分时段销售标记(当前观测全部为 2。 【ODS来源】store_goods_master - time_slot_sale。 【JSON字段】store_goods_master.json - data.orderGoodsList - time_slot_sale。';
-- ============================================================
-- 变更 3: DWD 层 — dim_tenant_goods_ex.commodity_code_list 改为 TEXT[]
-- ============================================================
-- 先将现有 VARCHAR 数据迁移到数组类型
ALTER TABLE dwd.dim_tenant_goods_ex
ALTER COLUMN commodity_code_list TYPE TEXT[]
USING CASE
WHEN commodity_code_list IS NULL THEN NULL
WHEN commodity_code_list = '' THEN '{}'::TEXT[]
ELSE ARRAY[commodity_code_list]
END;
COMMENT ON COLUMN dwd.dim_tenant_goods_ex.commodity_code_list IS
'【说明】商品编码数组(合并自 ODS commodityCode 数组字段)。单值时为单元素数组。 【ODS来源】tenant_goods_master - commodityCodeJSON 数组格式,如 ["10000028"])。 【JSON字段】tenant_goods_master.json - data.tenantGoodsList - commodityCode。';
COMMIT;
-- ============================================================
-- 回滚策略
-- ============================================================
-- BEGIN;
-- ALTER TABLE ods.store_goods_master DROP COLUMN IF EXISTS time_slot_sale;
-- ALTER TABLE dwd.dim_store_goods_ex DROP COLUMN IF EXISTS time_slot_sale;
-- ALTER TABLE dwd.dim_tenant_goods_ex
-- ALTER COLUMN commodity_code_list TYPE VARCHAR(256)
-- USING CASE
-- WHEN commodity_code_list IS NULL THEN NULL
-- WHEN array_length(commodity_code_list, 1) IS NULL THEN ''
-- ELSE commodity_code_list[1]
-- END;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 ODS time_slot_sale 列已创建
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods' AND table_name = 'store_goods_master'
-- AND column_name = 'time_slot_sale';
-- 2. 确认 DWD time_slot_sale 列已创建
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd' AND table_name = 'dim_store_goods_ex'
-- AND column_name = 'time_slot_sale';
-- 3. 确认 commodity_code_list 类型已变更为 ARRAY
-- SELECT column_name, data_type, udt_name
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd' AND table_name = 'dim_tenant_goods_ex'
-- AND column_name = 'commodity_code_list';
-- 4. 确认现有 commodity_code_list 数据已正确迁移
-- SELECT tenant_goods_id, commodity_code_list
-- FROM dwd.dim_tenant_goods_ex
-- WHERE scd2_is_current = 1 AND commodity_code_list IS NOT NULL
-- LIMIT 5;

View File

@@ -0,0 +1,78 @@
-- 迁移dws_assistant_monthly_summary 唯一约束变更
-- 日期2026-02-22
-- 关联:需求 A需求 2.2)— 助教月度聚合按档位分段统计
-- 影响dws.dws_assistant_monthly_summary 唯一约束从 (site_id, assistant_id, stat_month)
-- 变更为 (site_id, assistant_id, stat_month, assistant_level_code)
-- 原因:助教月内可能因升级/降级而存在多个 assistant_level_code
-- 需按档位分段统计业绩,旧约束不允许同一助教同月多行记录
-- 幂等DROP IF EXISTS + 先检查再 ADD可重复执行
BEGIN;
-- ============================================================
-- 1. 删除旧唯一约束
-- ============================================================
ALTER TABLE dws.dws_assistant_monthly_summary
DROP CONSTRAINT IF EXISTS uk_dws_assistant_monthly;
-- ============================================================
-- 2. 创建新唯一约束(加入 assistant_level_code
-- ============================================================
ALTER TABLE dws.dws_assistant_monthly_summary
ADD CONSTRAINT uk_dws_assistant_monthly
UNIQUE (site_id, assistant_id, stat_month, assistant_level_code);
COMMIT;
-- ============================================================
-- 回滚(需手动执行,不在事务内)
-- ============================================================
-- ⚠️ 回滚前须先清理同一 (site_id, assistant_id, stat_month) 的多行数据,
-- 否则恢复旧约束会因重复键失败。
--
-- 步骤 1清理多档位数据保留每组最新一条
-- DELETE FROM dws.dws_assistant_monthly_summary a
-- USING (
-- SELECT site_id, assistant_id, stat_month,
-- MAX(updated_at) AS keep_updated_at
-- FROM dws.dws_assistant_monthly_summary
-- GROUP BY site_id, assistant_id, stat_month
-- ) b
-- WHERE a.site_id = b.site_id
-- AND a.assistant_id = b.assistant_id
-- AND a.stat_month = b.stat_month
-- AND a.updated_at <> b.keep_updated_at;
--
-- 步骤 2恢复旧约束
-- BEGIN;
-- ALTER TABLE dws.dws_assistant_monthly_summary
-- DROP CONSTRAINT IF EXISTS uk_dws_assistant_monthly;
-- ALTER TABLE dws.dws_assistant_monthly_summary
-- ADD CONSTRAINT uk_dws_assistant_monthly
-- UNIQUE (site_id, assistant_id, stat_month);
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认新约束存在且列组合正确
-- SELECT conname, pg_get_constraintdef(oid) AS constraint_def
-- FROM pg_constraint
-- WHERE conrelid = 'dws.dws_assistant_monthly_summary'::regclass
-- AND conname = 'uk_dws_assistant_monthly';
-- 预期1 行constraint_def 包含 (site_id, assistant_id, stat_month, assistant_level_code)
-- 2. 确认约束列数为 4
-- SELECT COUNT(*) AS col_count
-- FROM pg_constraint c
-- JOIN LATERAL unnest(c.conkey) AS col_num ON TRUE
-- WHERE c.conrelid = 'dws.dws_assistant_monthly_summary'::regclass
-- AND c.conname = 'uk_dws_assistant_monthly';
-- 预期4
-- 3. 确认旧的 3 列约束不存在(无同名但只有 3 列的约束)
-- SELECT conname, array_length(conkey, 1) AS col_count
-- FROM pg_constraint
-- WHERE conrelid = 'dws.dws_assistant_monthly_summary'::regclass
-- AND contype = 'u';
-- 预期uk_dws_assistant_monthly 的 col_count = 4非 3

View File

@@ -0,0 +1,51 @@
-- =============================================================================
-- 迁移脚本dws_assistant_salary_calc 唯一约束变更
-- 说明:配合档位分段工资计算,唯一键加入 assistant_level_code
-- 日期2026-02-22
-- 关联需求:需求 A助教月度聚合按档位分段统计— 任务 7.4
-- =============================================================================
-- ---- 正向迁移 ----
-- 1. 删除旧唯一约束
ALTER TABLE dws.dws_assistant_salary_calc
DROP CONSTRAINT IF EXISTS uk_dws_assistant_salary;
-- 2. 创建新唯一约束(加入 assistant_level_code
ALTER TABLE dws.dws_assistant_salary_calc
ADD CONSTRAINT uk_dws_assistant_salary
UNIQUE (site_id, assistant_id, salary_month, assistant_level_code);
-- ---- 回滚 ----
-- ALTER TABLE dws.dws_assistant_salary_calc
-- DROP CONSTRAINT IF EXISTS uk_dws_assistant_salary;
-- ALTER TABLE dws.dws_assistant_salary_calc
-- ADD CONSTRAINT uk_dws_assistant_salary
-- UNIQUE (site_id, assistant_id, salary_month);
-- ---- 验证 SQL ----
-- 1. 确认新约束存在且包含 4 列
-- SELECT conname, array_agg(a.attname ORDER BY x.n)
-- FROM pg_constraint c
-- JOIN pg_class r ON r.oid = c.conrelid
-- JOIN pg_namespace ns ON ns.oid = r.relnamespace
-- CROSS JOIN LATERAL unnest(c.conkey) WITH ORDINALITY AS x(attnum, n)
-- JOIN pg_attribute a ON a.attrelid = r.oid AND a.attnum = x.attnum
-- WHERE ns.nspname = 'dws' AND r.relname = 'dws_assistant_salary_calc'
-- AND c.contype = 'u'
-- GROUP BY conname;
-- 预期: uk_dws_assistant_salary | {site_id,assistant_id,salary_month,assistant_level_code}
-- 2. 确认旧约束不存在(只有一个唯一约束)
-- SELECT count(*) FROM pg_constraint c
-- JOIN pg_class r ON r.oid = c.conrelid
-- JOIN pg_namespace ns ON ns.oid = r.relnamespace
-- WHERE ns.nspname = 'dws' AND r.relname = 'dws_assistant_salary_calc'
-- AND c.contype = 'u';
-- 预期: 1
-- 3. 测试插入同一助教同月不同档位不冲突
-- INSERT INTO dws.dws_assistant_salary_calc (site_id, tenant_id, assistant_id, salary_month, assistant_level_code)
-- VALUES (1, 1, 100, '2026-01-01', 10), (1, 1, 100, '2026-01-01', 20);
-- 预期: 成功插入 2 行
-- DELETE FROM dws.dws_assistant_salary_calc WHERE site_id = 1 AND assistant_id = 100 AND salary_month = '2026-01-01';

View File

@@ -0,0 +1,58 @@
-- 迁移ODS/DWD 层会员表新增 birthday 列
-- 日期2026-02-22
-- 关联:需求 C1需求 4.1)— 会员生日字段 ETL 链路补齐
-- 影响ods.member_profiles 加列、dwd.dim_member 加列
-- 幂等ADD COLUMN IF NOT EXISTS可重复执行
BEGIN;
-- ============================================================
-- 1. ODS 层member_profiles 加 birthday 列
-- ============================================================
ALTER TABLE ods.member_profiles
ADD COLUMN IF NOT EXISTS birthday DATE;
COMMENT ON COLUMN ods.member_profiles.birthday
IS '会员生日,来源:上游 API payload 中的 birthday 字段';
-- ============================================================
-- 2. DWD 层dim_member 加 birthday 列
-- ============================================================
ALTER TABLE dwd.dim_member
ADD COLUMN IF NOT EXISTS birthday DATE;
COMMENT ON COLUMN dwd.dim_member.birthday
IS '会员生日来源ODS member_profiles payload 中的 birthday 字段';
COMMIT;
-- ============================================================
-- 回滚(需手动执行,不在事务内)
-- ============================================================
-- BEGIN;
-- ALTER TABLE ods.member_profiles DROP COLUMN IF EXISTS birthday;
-- ALTER TABLE dwd.dim_member DROP COLUMN IF EXISTS birthday;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 ods.member_profiles.birthday 列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'ods'
-- AND table_name = 'member_profiles'
-- AND column_name = 'birthday';
-- 2. 确认 dwd.dim_member.birthday 列存在
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'dwd'
-- AND table_name = 'dim_member'
-- AND column_name = 'birthday';
-- 3. 确认列注释已设置
-- SELECT col_description(
-- (SELECT oid FROM pg_class WHERE relname = 'dim_member' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dwd')),
-- (SELECT ordinal_position FROM information_schema.columns WHERE table_schema = 'dwd' AND table_name = 'dim_member' AND column_name = 'birthday')
-- );

View File

@@ -0,0 +1,77 @@
-- 迁移删除助教废除Abolish独立链路的数据库对象
-- 日期2026-02-22
-- 关联:助教废除全链路清理(需求 5.15.5
-- 原因:上游"助教废除记录"API 的独立数据链路已废弃。
-- 废除表 dwd_assistant_trash_event 无法与服务记录表做 1:1 关联(缺少外键),
-- DWS 层已改用 dwd_assistant_service_log_ex.is_trash 字段直接判断废除,
-- 整条 ODS → DWD 独立链路不再有消费者,属于死数据。
-- 影响:删除 3 张表 + 1 个索引,不影响 dwd_assistant_service_log_ex 中的
-- is_trash / trash_reason / trash_applicant_* 字段(保留)
-- 幂等:所有语句使用 IF EXISTS可重复执行
BEGIN;
-- ============================================================
-- 1. 删除 ODS 层索引
-- ============================================================
-- 该索引服务于 assistant_cancellation_records 的最新版本查询,表删除后索引无意义
DROP INDEX IF EXISTS ods.idx_ods_assistant_cancellation_records_latest;
-- ============================================================
-- 2. 删除 DWD 层废除表(先删扩展表,再删主表)
-- ============================================================
-- dwd_assistant_trash_event_ex废除事件扩展表无消费者
DROP TABLE IF EXISTS dwd.dwd_assistant_trash_event_ex;
-- dwd_assistant_trash_event废除事件主表无消费者
DROP TABLE IF EXISTS dwd.dwd_assistant_trash_event;
-- ============================================================
-- 3. 删除 ODS 层原始表
-- ============================================================
-- assistant_cancellation_records上游废除 API 原始数据(仅 78 条),不再抓取
DROP TABLE IF EXISTS ods.assistant_cancellation_records;
-- ============================================================
-- 4. 清理 meta 层任务注册(如存在)
-- ============================================================
-- 移除 ODS_ASSISTANT_ABOLISH 的调度注册,防止调度器尝试执行已删除的任务
DELETE FROM meta.etl_task WHERE task_code = 'ODS_ASSISTANT_ABOLISH';
COMMIT;
-- ============================================================
-- 回滚策略(需手动执行,不在事务内)
-- ============================================================
-- 1. 从 db/etl_feiqiu/schemas/ods.sql 中恢复 assistant_cancellation_records 的 CREATE TABLE
-- 2. 从 db/etl_feiqiu/schemas/dwd.sql 中恢复 dwd_assistant_trash_event / _ex 的 CREATE TABLE
-- 3. 重建索引:
-- CREATE INDEX idx_ods_assistant_cancellation_records_latest
-- ON ods.assistant_cancellation_records (id, fetched_at DESC);
-- 4. 重新注册任务:
-- INSERT INTO meta.etl_task (task_code, store_id, enabled)
-- VALUES ('ODS_ASSISTANT_ABOLISH', <store_id>, TRUE);
-- 5. 数据不可恢复ODS 仅 78 条,可从上游 API 重新抓取)
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认 3 张表已不存在
-- SELECT tablename FROM pg_tables
-- WHERE schemaname IN ('ods', 'dwd')
-- AND tablename IN (
-- 'assistant_cancellation_records',
-- 'dwd_assistant_trash_event',
-- 'dwd_assistant_trash_event_ex'
-- );
-- 预期0 行
-- 2. 确认索引已不存在
-- SELECT indexname FROM pg_indexes
-- WHERE schemaname = 'ods'
-- AND indexname = 'idx_ods_assistant_cancellation_records_latest';
-- 预期0 行
-- 3. 确认 meta.etl_task 中无 ODS_ASSISTANT_ABOLISH 注册
-- SELECT * FROM meta.etl_task WHERE task_code = 'ODS_ASSISTANT_ABOLISH';
-- 预期0 行

View File

@@ -0,0 +1,41 @@
-- 迁移:修复 DWD 层 BC 哨兵日期0001-12-31 23:59:43 BC→ NULL
-- 日期2026-02-22
-- 关联BUG 12 — 上游 API 返回 0001-01-01T00:00:00 哨兵值,
-- ODS timestamp 转 DWD timestamptz 时在 Asia/Shanghai 时区下变为 BC 日期,
-- psycopg2 无法解析 BC 日期导致 ValueError。
-- 影响6 个 DWD 表/列,共约 69,668 行
-- 幂等可重复执行WHERE 条件仅匹配 year < 1 的行
BEGIN;
-- 1. dwd.dim_assistant_ex.birth_date约 1,107 行)
UPDATE dwd.dim_assistant_ex
SET birth_date = NULL
WHERE EXTRACT(year FROM birth_date) < 1;
-- 2. dwd.dim_member_card_account_ex.disable_start_time约 18,172 行)
UPDATE dwd.dim_member_card_account_ex
SET disable_start_time = NULL
WHERE EXTRACT(year FROM disable_start_time) < 1;
-- 3. dwd.dim_member_card_account_ex.disable_end_time约 18,172 行)
UPDATE dwd.dim_member_card_account_ex
SET disable_end_time = NULL
WHERE EXTRACT(year FROM disable_end_time) < 1;
-- 4. dwd.dwd_assistant_service_log_ex.composite_grade_time约 5,297 行)
UPDATE dwd.dwd_assistant_service_log_ex
SET composite_grade_time = NULL
WHERE EXTRACT(year FROM composite_grade_time) < 1;
-- 5. dwd.dwd_recharge_order_ex.revoke_time约 485 行)
UPDATE dwd.dwd_recharge_order_ex
SET revoke_time = NULL
WHERE EXTRACT(year FROM revoke_time) < 1;
-- 6. dwd.dwd_settlement_head_ex.revoke_time约 26,435 行)
UPDATE dwd.dwd_settlement_head_ex
SET revoke_time = NULL
WHERE EXTRACT(year FROM revoke_time) < 1;
COMMIT;

View File

@@ -1,6 +1,19 @@
CREATE SCHEMA IF NOT EXISTS dwd;
SET search_path TO dwd;
-- ============================================================
-- 【哨兵日期约定】
-- 上游飞球 API 对"未设置"的日期字段返回 0001-01-01T00:00:00哨兵值
-- ODS 层以 timestamp 原样存储DWD 层转为 timestamptz 时ETL 代码
-- 将 < 0002-01-01 的值统一置为 NULL避免 BC 日期解析异常。
-- 受影响列dim_assistant_ex.birth_date,
-- dim_member_card_account_ex.disable_start_time / disable_end_time,
-- dwd_assistant_service_log_ex.composite_grade_time,
-- dwd_settlement_head_ex.revoke_time,
-- dwd_recharge_order_ex.revoke_time
-- 参见:迁移 112026-02-22__fix_bc_sentinel_dates_to_null.sql
-- ============================================================
CREATE EXTENSION IF NOT EXISTS btree_gist;
DO $$
@@ -201,6 +214,20 @@ CREATE TABLE IF NOT EXISTS dim_table_ex (
table_cloth_use_time INTEGER,
table_cloth_use_cycle INTEGER,
table_status INTEGER,
create_time TIMESTAMPTZ,
light_status INTEGER,
tablestatusname TEXT,
sitename TEXT,
applet_qr_code_url TEXT,
audit_status INTEGER,
charge_free INTEGER,
delay_lights_time INTEGER,
is_rest_area INTEGER,
only_allow_groupon INTEGER,
order_delay_time INTEGER,
self_table INTEGER,
temporary_light_second INTEGER,
virtual_table INTEGER,
SCD2_start_time TIMESTAMPTZ DEFAULT now(),
SCD2_end_time TIMESTAMPTZ DEFAULT '9999-12-31',
SCD2_is_current INT DEFAULT 1,
@@ -215,6 +242,20 @@ COMMENT ON COLUMN dwd.dim_table_ex.is_online_reservation IS '【说明】布尔/
COMMENT ON COLUMN dwd.dim_table_ex.table_cloth_use_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】1863727时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】site_tables_master - table_cloth_use_time。 【JSON字段】site_tables_master.json - data.siteTables - table_cloth_use_time。';
COMMENT ON COLUMN dwd.dim_table_ex.table_cloth_use_cycle IS '【说明】维度字段,用于补充维度属性。 【示例】0维度字段用于补充维度属性。 【ODS来源】site_tables_master - table_cloth_use_Cycle。 【JSON字段】site_tables_master.json - data.siteTables - table_cloth_use_Cycle。';
COMMENT ON COLUMN dwd.dim_table_ex.table_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】1状态枚举字段用于标识业务状态。 【ODS来源】site_tables_master - table_status。 【JSON字段】site_tables_master.json - data.siteTables - table_status。';
COMMENT ON COLUMN dwd.dim_table_ex.create_time IS '【说明】台桌配置的创建时间或最近一次创建/复制时间。 【示例】2025-07-15 17:52:54。 【ODS来源】site_tables_master - create_time。 【JSON字段】site_tables_master.json - data.siteTables - create_time。';
COMMENT ON COLUMN dwd.dim_table_ex.light_status IS '【说明】台灯状态枚举(如 2=已开灯),用于标识台桌灯光当前状态。 【示例】2。 【ODS来源】site_tables_master - light_status。 【JSON字段】site_tables_master.json - data.siteTables - light_status。';
COMMENT ON COLUMN dwd.dim_table_ex.tablestatusname IS '【说明】台桌状态中文名称(如"空闲中""使用中"),仅展示用途。 【示例】空闲中。 【ODS来源】site_tables_master - tablestatusname。 【JSON字段】site_tables_master.json - data.siteTables - tableStatusName。';
COMMENT ON COLUMN dwd.dim_table_ex.sitename IS '【说明】门店名称快照,冗余字段,配合 site_id 使用。 【示例】朗朗桌球。 【ODS来源】site_tables_master - sitename。 【JSON字段】site_tables_master.json - data.siteTables - siteName。';
COMMENT ON COLUMN dwd.dim_table_ex.applet_qr_code_url IS '【说明】小程序二维码 URL用于扫码开台等场景。 【ODS来源】site_tables_master - appletQrCodeUrl。 【JSON字段】site_tables_master.json - data.siteTables - appletQrCodeUrl。';
COMMENT ON COLUMN dwd.dim_table_ex.audit_status IS '【说明】审核状态枚举(当前全部为 2含义待确认。 【示例】2。 【ODS来源】site_tables_master - audit_status。 【JSON字段】site_tables_master.json - data.siteTables - audit_status。';
COMMENT ON COLUMN dwd.dim_table_ex.charge_free IS '【说明】是否免费台0=收费1=免费),当前全部为 0。 【示例】0。 【ODS来源】site_tables_master - charge_free。 【JSON字段】site_tables_master.json - data.siteTables - charge_free。';
COMMENT ON COLUMN dwd.dim_table_ex.delay_lights_time IS '【说明】台灯熄灭延迟时间(单位秒或分钟),结账后延时关灯。 【示例】0。 【ODS来源】site_tables_master - delay_lights_time。 【JSON字段】site_tables_master.json - data.siteTables - delay_lights_time。';
COMMENT ON COLUMN dwd.dim_table_ex.is_rest_area IS '【说明】是否休息区台桌0=否1=是),当前全部为 0。 【示例】0。 【ODS来源】site_tables_master - is_rest_area。 【JSON字段】site_tables_master.json - data.siteTables - is_rest_area。';
COMMENT ON COLUMN dwd.dim_table_ex.only_allow_groupon IS '【说明】是否仅允许团购开台0/1/2 枚举)。 【示例】2。 【ODS来源】site_tables_master - only_allow_groupon。 【JSON字段】site_tables_master.json - data.siteTables - only_allow_groupon。';
COMMENT ON COLUMN dwd.dim_table_ex.order_delay_time IS '【说明】订单自动延时时长(到点后自动延长继续计费的时间)。 【示例】0。 【ODS来源】site_tables_master - order_delay_time。 【JSON字段】site_tables_master.json - data.siteTables - order_delay_time。';
COMMENT ON COLUMN dwd.dim_table_ex.self_table IS '【说明】是否自有台桌1=自有),当前全部为 1。 【示例】1。 【ODS来源】site_tables_master - self_table。 【JSON字段】site_tables_master.json - data.siteTables - self_table。';
COMMENT ON COLUMN dwd.dim_table_ex.temporary_light_second IS '【说明】临时开灯秒数,用于短时照明场景。 【示例】0。 【ODS来源】site_tables_master - temporary_light_second。 【JSON字段】site_tables_master.json - data.siteTables - temporary_light_second。';
COMMENT ON COLUMN dwd.dim_table_ex.virtual_table IS '【说明】是否虚拟台桌0=实体台1=虚拟台)。 【示例】0。 【ODS来源】site_tables_master - virtual_table。 【JSON字段】site_tables_master.json - data.siteTables - virtual_table。';
COMMENT ON COLUMN dwd.dim_table_ex.scd2_start_time IS '【说明】SCD2 开始时间(版本生效起点),用于维度慢变追踪。 【示例】2025-11-10T00:00:00+08:00SCD2 开始时间(版本生效起点),用于维度慢变追踪)。 【ODS来源】site_tables_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_table_ex.scd2_end_time IS '【说明】SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪。 【示例】9999-12-31T00:00:00+00:00SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪)。 【ODS来源】site_tables_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_table_ex.scd2_is_current IS '【说明】SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录。 【示例】1SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录)。 【ODS来源】site_tables_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
@@ -311,6 +352,10 @@ CREATE TABLE IF NOT EXISTS dim_assistant_ex (
light_status INTEGER,
is_team_leader INTEGER,
serial_number BIGINT,
system_role_id BIGINT,
job_num TEXT,
cx_unit_price NUMERIC(18,2),
pd_unit_price NUMERIC(18,2),
SCD2_start_time TIMESTAMPTZ,
SCD2_end_time TIMESTAMPTZ,
SCD2_is_current INT,
@@ -319,9 +364,13 @@ CREATE TABLE IF NOT EXISTS dim_assistant_ex (
);
COMMENT ON TABLE dwd.dim_assistant_ex IS 'DWD 维度表扩展字段表dim_assistant_ex。ODS 来源表billiards_ods.assistant_accounts_master对应 JSONassistant_accounts_master.json分析assistant_accounts_master-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN dwd.dim_assistant_ex.system_role_id IS '【说明】系统角色 ID标识助教在系统中的角色类型。 【ODS来源】assistant_accounts_master - system_role_id。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - system_role_id。';
COMMENT ON COLUMN dwd.dim_assistant_ex.job_num IS '【说明】工号,助教的内部编号标识。 【ODS来源】assistant_accounts_master - job_num。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - job_num。';
COMMENT ON COLUMN dwd.dim_assistant_ex.cx_unit_price IS '【说明】促销单价(元),助教提供促销服务时的计费单价。 【ODS来源】assistant_accounts_master - cx_unit_price。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - cx_unit_price。';
COMMENT ON COLUMN dwd.dim_assistant_ex.pd_unit_price IS '【说明】陪打单价(元),助教提供陪打服务时的计费单价。 【ODS来源】assistant_accounts_master - pd_unit_price。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - pd_unit_price。';
COMMENT ON COLUMN dwd.dim_assistant_ex.assistant_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2947562271297029标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_accounts_master - id。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - id。';
COMMENT ON COLUMN dwd.dim_assistant_ex.gender IS '【说明】维度字段,用于补充维度属性。 【示例】0维度字段用于补充维度属性。 【ODS来源】assistant_accounts_master - gender。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - gender。';
COMMENT ON COLUMN dwd.dim_assistant_ex.birth_date IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】0001-01-01 00:00:00(时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】assistant_accounts_master - birth_date。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - birth_date。';
COMMENT ON COLUMN dwd.dim_assistant_ex.birth_date IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】assistant_accounts_master - birth_date。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - birth_date。';
COMMENT ON COLUMN dwd.dim_assistant_ex.avatar IS '【说明】维度字段,用于补充维度属性。 【示例】https://oss.ficoo.vip/maUiImages/images/defaultAvatar.png维度字段用于补充维度属性。 【ODS来源】assistant_accounts_master - avatar。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - avatar。';
COMMENT ON COLUMN dwd.dim_assistant_ex.introduce IS '【说明】维度字段,用于补充维度属性。 【示例】NULL维度字段用于补充维度属性。 【ODS来源】assistant_accounts_master - introduce。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - introduce。';
COMMENT ON COLUMN dwd.dim_assistant_ex.video_introduction_url IS '【说明】维度字段,用于补充维度属性。 【示例】https://oss.ficoo.vip/cbb/userVideo/1753096246308/175309624630830.mp4维度字段用于补充维度属性。 【ODS来源】assistant_accounts_master - video_introduction_url。 【JSON字段】assistant_accounts_master.json - data.assistantInfos - video_introduction_url。';
@@ -382,6 +431,7 @@ CREATE TABLE IF NOT EXISTS dim_member (
update_time TIMESTAMPTZ,
pay_money_sum NUMERIC(18,2),
recharge_money_sum NUMERIC(18,2),
birthday DATE,
SCD2_start_time TIMESTAMPTZ,
SCD2_end_time TIMESTAMPTZ,
SCD2_is_current INT,
@@ -400,6 +450,7 @@ COMMENT ON COLUMN dwd.dim_member.member_card_grade_code IS '【说明】维度
COMMENT ON COLUMN dwd.dim_member.member_card_grade_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】储值卡(名称字段,用于展示与辅助识别)。 【ODS来源】member_profiles - member_card_grade_name。 【JSON字段】member_profiles.json - data.tenantMemberInfos - member_card_grade_name。';
COMMENT ON COLUMN dwd.dim_member.create_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】2025-11-08 01:29:33时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】member_profiles - create_time。 【JSON字段】member_profiles.json - data.tenantMemberInfos - create_time。';
COMMENT ON COLUMN dwd.dim_member.update_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】NULL时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】member_profiles - update_time。 【JSON字段】member_profiles.json - data.tenantMemberInfos - update_time。';
COMMENT ON COLUMN dwd.dim_member.birthday IS '【说明】会员生日来源ODS member_profiles payload 中的 birthday 字段。 【ODS来源】member_profiles - birthday。 【JSON字段】member_profiles.json - data.tenantMemberInfos - birthday。';
COMMENT ON COLUMN dwd.dim_member.scd2_start_time IS '【说明】SCD2 开始时间(版本生效起点),用于维度慢变追踪。 【示例】2025-11-10T00:00:00+08:00SCD2 开始时间(版本生效起点),用于维度慢变追踪)。 【ODS来源】member_profiles - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_member.scd2_end_time IS '【说明】SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪。 【示例】9999-12-31T00:00:00+00:00SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪)。 【ODS来源】member_profiles - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_member.scd2_is_current IS '【说明】SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录。 【示例】1SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录)。 【ODS来源】member_profiles - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
@@ -567,8 +618,8 @@ COMMENT ON COLUMN dwd.dim_member_card_account_ex.bind_password IS '【说明】
COMMENT ON COLUMN dwd.dim_member_card_account_ex.use_scene IS '【说明】维度字段,用于补充维度属性。 【示例】NULL维度字段用于补充维度属性。 【ODS来源】member_stored_value_cards - use_scene。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - use_scene。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.denomination IS '【说明】维度字段,用于补充维度属性。 【示例】0.0(维度字段,用于补充维度属性)。 【ODS来源】member_stored_value_cards - denomination。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - denomination。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.create_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】2025-11-08 01:31:12时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】member_stored_value_cards - create_time。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - create_time。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.disable_start_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】0001-01-01 00:00:00(时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】member_stored_value_cards - disable_start_time。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - disable_start_time。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.disable_end_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】0001-01-01 00:00:00(时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】member_stored_value_cards - disable_end_time。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - disable_end_time。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.disable_start_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】member_stored_value_cards - disable_start_time。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - disable_start_time。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.disable_end_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】member_stored_value_cards - disable_end_time。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - disable_end_time。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.is_allow_give IS '【说明】布尔/开关字段,用于表示是否/可用性等业务开关。 【示例】0布尔/开关字段,用于表示是否/可用性等业务开关)。 【ODS来源】member_stored_value_cards - is_allow_give。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - is_allow_give。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.is_allow_order_deduct IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0金额字段用于计费/结算/核算等金额计算)。 【ODS来源】member_stored_value_cards - is_allow_order_deduct。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - is_allow_order_deduct。';
COMMENT ON COLUMN dwd.dim_member_card_account_ex.sort IS '【说明】维度字段,用于补充维度属性。 【示例】1维度字段用于补充维度属性。 【ODS来源】member_stored_value_cards - sort。 【JSON字段】member_stored_value_cards.json - data.tenantMemberCards - sort。';
@@ -664,7 +715,7 @@ CREATE TABLE IF NOT EXISTS dim_tenant_goods_ex (
goods_cover VARCHAR(512),
goods_bar_code VARCHAR(64),
commodity_code VARCHAR(64),
commodity_code_list VARCHAR(256),
commodity_code_list TEXT[], -- CHANGE 2026-02-21 | VARCHAR→TEXT[] 数组类型,支持多编码
min_discount_price NUMERIC(18,2),
cost_price NUMERIC(18,2),
cost_price_type INTEGER,
@@ -748,7 +799,7 @@ COMMENT ON COLUMN dwd.dim_store_goods.goods_category_id IS '【说明】标识
COMMENT ON COLUMN dwd.dim_store_goods.goods_second_category_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2793236829620037标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】store_goods_master - goods_second_category_id。 【JSON字段】store_goods_master.json - data.orderGoodsList - goods_second_category_id。';
COMMENT ON COLUMN dwd.dim_store_goods.category_level1_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】零食(名称字段,用于展示与辅助识别)。 【ODS来源】store_goods_master - oneCategoryName。 【JSON字段】store_goods_master.json - data.orderGoodsList - oneCategoryName。';
COMMENT ON COLUMN dwd.dim_store_goods.category_level2_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】面(名称字段,用于展示与辅助识别)。 【ODS来源】store_goods_master - twoCategoryName。 【JSON字段】store_goods_master.json - data.orderGoodsList - twoCategoryName。';
COMMENT ON COLUMN dwd.dim_store_goods.batch_stock_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】18数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - stock';
COMMENT ON COLUMN dwd.dim_store_goods.batch_stock_qty IS '【说明】批次库存数量区别于当前库存stock。 【示例】18。 【ODS来源】store_goods_master - batch_stock_quantity。 【JSON字段】store_goods_master.json - data.orderGoodsList - batchStockQuantity';
COMMENT ON COLUMN dwd.dim_store_goods.sale_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】104数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - sale_num。 【JSON字段】store_goods_master.json - data.orderGoodsList - sale_num。';
COMMENT ON COLUMN dwd.dim_store_goods.total_sales_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】104数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - total_sales。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_sales。';
COMMENT ON COLUMN dwd.dim_store_goods.sale_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】12.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - sale_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - sale_price。';
@@ -792,6 +843,8 @@ CREATE TABLE IF NOT EXISTS dim_store_goods_ex (
option_required INTEGER,
remark TEXT,
sort_order INTEGER,
batch_stock_quantity NUMERIC(18,2), -- CHANGE 2026-02-21 | 修正类型:与 DB 实际一致(迁移脚本用 NUMERIC(18,2)
time_slot_sale INTEGER, -- CHANGE 2026-02-21 | 新增:分时段销售标记
SCD2_start_time TIMESTAMPTZ,
SCD2_end_time TIMESTAMPTZ,
SCD2_is_current INT,
@@ -799,6 +852,7 @@ CREATE TABLE IF NOT EXISTS dim_store_goods_ex (
PRIMARY KEY (site_goods_id, scd2_start_time)
);
COMMENT ON COLUMN dwd.dim_store_goods_ex.time_slot_sale IS '【说明】分时段销售标记(当前观测全部为 2。 【ODS来源】store_goods_master - time_slot_sale。 【JSON字段】store_goods_master.json - data.orderGoodsList - time_slot_sale。';
COMMENT ON TABLE dwd.dim_store_goods_ex IS 'DWD 维度表扩展字段表dim_store_goods_ex。ODS 来源表billiards_ods.store_goods_master对应 JSONstore_goods_master.json分析store_goods_master-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN dwd.dim_store_goods_ex.site_goods_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2793025851560005标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】store_goods_master - id。 【JSON字段】store_goods_master.json - data.orderGoodsList - id。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.site_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】朗朗桌球(名称字段,用于展示与辅助识别)。 【ODS来源】store_goods_master - siteName。 【JSON字段】store_goods_master.json - data.orderGoodsList - siteName。';
@@ -811,7 +865,7 @@ COMMENT ON COLUMN dwd.dim_store_goods_ex.stock_secondary_qty IS '【说明】数
COMMENT ON COLUMN dwd.dim_store_goods_ex.safety_stock_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】0数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - safe_stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - safe_stock。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.cost_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - cost_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - cost_price。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.cost_price_type IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】1金额字段用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - cost_price_type。 【JSON字段】store_goods_master.json - data.orderGoodsList - cost_price_type。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.provisional_total_cost IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - total_purchase_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_purchase_cost。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.provisional_total_cost IS '【说明】暂估总成本区别于实际采购成本total_purchase_cost。 【示例】0.0。 【ODS来源】store_goods_master - provisional_total_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - provisionalTotalCost。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.total_purchase_cost IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - total_purchase_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_purchase_cost。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.min_discount_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】7.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - min_discount_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - min_discount_price。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.is_discountable IS '【说明】数量/时长字段,用于统计与计量。 【示例】1数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - able_discount。 【JSON字段】store_goods_master.json - data.orderGoodsList - able_discount。';
@@ -826,6 +880,7 @@ COMMENT ON COLUMN dwd.dim_store_goods_ex.custom_label_type IS '【说明】维
COMMENT ON COLUMN dwd.dim_store_goods_ex.option_required IS '【说明】维度字段,用于补充维度属性。 【示例】1维度字段用于补充维度属性。 【ODS来源】store_goods_master - option_required。 【JSON字段】store_goods_master.json - data.orderGoodsList - option_required。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.remark IS '【说明】维度字段,用于补充维度属性。 【示例】NULL维度字段用于补充维度属性。 【ODS来源】store_goods_master - remark。 【JSON字段】store_goods_master.json - data.orderGoodsList - remark。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.sort_order IS '【说明】维度字段,用于补充维度属性。 【示例】100维度字段用于补充维度属性。 【ODS来源】store_goods_master - sort。 【JSON字段】store_goods_master.json - data.orderGoodsList - sort。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.batch_stock_quantity IS '【说明】批次库存数量,记录商品按批次管理的库存量。 【示例】0。 【ODS来源】store_goods_master - batch_stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - batch_stock。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.scd2_start_time IS '【说明】SCD2 开始时间(版本生效起点),用于维度慢变追踪。 【示例】2025-11-10T00:00:00+08:00SCD2 开始时间(版本生效起点),用于维度慢变追踪)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.scd2_end_time IS '【说明】SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪。 【示例】9999-12-31T00:00:00+00:00SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN dwd.dim_store_goods_ex.scd2_is_current IS '【说明】SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录。 【示例】1SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
@@ -1092,7 +1147,7 @@ COMMENT ON COLUMN dwd.dwd_settlement_head_ex.serial_number IS '【说明】数
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.settle_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】NULL状态枚举字段用于标识业务状态。 【ODS来源】settlement_records - settlestatus。 【JSON字段】settlement_records.json - $ - settlestatus。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.can_be_revoked IS '【说明】布尔/开关字段,用于表示是否/可用性等业务开关。 【示例】NULL布尔/开关字段,用于表示是否/可用性等业务开关)。 【ODS来源】settlement_records - canberevoked派生BOOLEAN(canberevoked))。 【JSON字段】settlement_records.json - $ - canberevoked派生BOOLEAN(canberevoked))。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.revoke_order_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】NULL名称字段用于展示与辅助识别。 【ODS来源】settlement_records - revokeordername。 【JSON字段】settlement_records.json - $ - revokeordername。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.revoke_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】NULL时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】settlement_records - revoketime。 【JSON字段】settlement_records.json - $ - revoketime。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.revoke_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】settlement_records - revoketime。 【JSON字段】settlement_records.json - $ - revoketime。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.is_first_order IS '【说明】布尔/开关字段,用于表示是否/可用性等业务开关。 【示例】NULL布尔/开关字段,用于表示是否/可用性等业务开关)。 【ODS来源】settlement_records - isfirst派生BOOLEAN(isfirst))。 【JSON字段】settlement_records.json - $ - isfirst派生BOOLEAN(isfirst))。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.service_money IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】NULL金额字段用于计费/结算/核算等金额计算)。 【ODS来源】settlement_records - servicemoney。 【JSON字段】settlement_records.json - $ - servicemoney。';
COMMENT ON COLUMN dwd.dwd_settlement_head_ex.cash_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】NULL金额字段用于计费/结算/核算等金额计算)。 【ODS来源】settlement_records - cashamount。 【JSON字段】settlement_records.json - $ - cashamount。';
@@ -1296,6 +1351,7 @@ CREATE TABLE IF NOT EXISTS dwd_store_goods_sale (
ledger_unit_price NUMERIC(18,2),
ledger_count INTEGER,
ledger_amount NUMERIC(18,2),
discount_money NUMERIC(18,2),
discount_price NUMERIC(18,2),
real_goods_money NUMERIC(18,2),
cost_money NUMERIC(18,2),
@@ -1324,7 +1380,8 @@ COMMENT ON COLUMN dwd.dwd_store_goods_sale.ledger_group_name IS '【说明】名
COMMENT ON COLUMN dwd.dwd_store_goods_sale.ledger_unit_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - ledger_unit_price。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_unit_price。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.ledger_count IS '【说明】数量/时长字段,用于统计与计量。 【示例】1数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_sales_records - ledger_count。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_count。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.ledger_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - ledger_amount。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_amount。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - discount_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_money IS '【说明】折扣金额,即原价被减免的金额部分。 【示例】0.0。 【ODS来源】store_goods_sales_records - discount_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.discount_price IS '【说明】折后单价(元/单位),即应用折扣后的商品单价。 【示例】5.00。 【ODS来源】store_goods_sales_records - discount_price。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_price。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.real_goods_money IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - real_goods_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - real_goods_money。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.cost_money IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.01(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - cost_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - cost_money。';
COMMENT ON COLUMN dwd.dwd_store_goods_sale.ledger_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】1状态枚举字段用于标识业务状态。 【ODS来源】store_goods_sales_records - ledger_status。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_status。';
@@ -1437,7 +1494,7 @@ COMMENT ON COLUMN dwd.dwd_assistant_service_log.assistant_service_id IS '【说
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_trade_no IS '【说明】明细字段,用于记录事实取值。 【示例】2957784612605829明细字段用于记录事实取值。 【ODS来源】assistant_service_records - order_trade_no。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_trade_no。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_settle_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957913171693253标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - order_settle_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_settle_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_pay_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】0标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - order_pay_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_pay_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_assistant_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957788717240005(标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - order_assistant_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_assistant_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_assistant_id IS '【说明】订单中助教项目明细的内部 ID订单级与 site_assistant_id档案级不同。 【示例】2957788717240005。 【ODS来源】assistant_service_records - order_assistant_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_assistant_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.order_assistant_type IS '【说明】明细字段,用于记录事实取值。 【示例】1明细字段用于记录事实取值。 【ODS来源】assistant_service_records - order_assistant_type。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_assistant_type。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.tenant_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790683160709957标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - tenant_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - tenant_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.site_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790685415443269标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - site_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - site_id。';
@@ -1446,7 +1503,7 @@ COMMENT ON COLUMN dwd.dwd_assistant_service_log.tenant_member_id IS '【说明
COMMENT ON COLUMN dwd.dwd_assistant_service_log.system_member_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】0标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - system_member_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - system_member_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.assistant_no IS '【说明】明细字段,用于记录事实取值。 【示例】27明细字段用于记录事实取值。 【ODS来源】assistant_service_records - assistantNo。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - assistantNo。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.nickname IS '【说明】名称字段,用于展示与辅助识别。 【示例】泡芙(名称字段,用于展示与辅助识别)。 【ODS来源】assistant_service_records - nickname。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - nickname。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.site_assistant_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957788717240005标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - order_assistant_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - order_assistant_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.site_assistant_id IS '【说明】门店维度的助教档案 ID关联 assistant_accounts_master.id。 【示例】2946266869435205。 【ODS来源】assistant_service_records - site_assistant_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - site_assistant_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.user_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2946266868976453标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - user_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - user_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.assistant_team_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2792011585884037标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - assistant_team_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - assistant_team_id。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log.person_org_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2946266869336901标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_service_records - person_org_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - person_org_id。';
@@ -1499,6 +1556,8 @@ CREATE TABLE IF NOT EXISTS dwd_assistant_service_log_ex (
grade_status INTEGER,
composite_grade_time TIMESTAMPTZ,
assistant_team_name TEXT,
operator_id BIGINT,
operator_name TEXT,
PRIMARY KEY (assistant_service_id)
);
@@ -1532,48 +1591,12 @@ COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.composite_grade IS '【说明
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.sum_grade IS '【说明】明细字段,用于记录事实取值。 【示例】0.0(明细字段,用于记录事实取值)。 【ODS来源】assistant_service_records - sum_grade。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - sum_grade。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.get_grade_times IS '【说明】明细字段,用于记录事实取值。 【示例】0明细字段用于记录事实取值。 【ODS来源】assistant_service_records - get_grade_times。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - get_grade_times。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.grade_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】1状态枚举字段用于标识业务状态。 【ODS来源】assistant_service_records - grade_status。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - grade_status。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.composite_grade_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】0001-01-01 00:00:00(时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】assistant_service_records - composite_grade_time。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - composite_grade_time。';
COMMENT ON COLUMN dwd.dwd_assistant_service_log_ex.composite_grade_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】assistant_service_records - composite_grade_time。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - composite_grade_time。';
CREATE TABLE IF NOT EXISTS dwd_assistant_trash_event (
assistant_trash_event_id BIGINT,
site_id BIGINT,
table_id BIGINT,
table_area_id BIGINT,
assistant_no VARCHAR(32),
assistant_name VARCHAR(64),
charge_minutes_raw INTEGER,
abolish_amount NUMERIC(18,2),
trash_reason VARCHAR(255),
create_time TIMESTAMPTZ,
tenant_id BIGINT,
PRIMARY KEY (assistant_trash_event_id)
);
COMMENT ON TABLE dwd.dwd_assistant_trash_event IS 'DWD 明细事实表dwd_assistant_trash_event。ODS 来源表billiards_ods.assistant_cancellation_records对应 JSONassistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.assistant_trash_event_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957675849518789标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - id。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.site_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790685415443269标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - siteId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteId。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.table_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2793016660660357标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - tableId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableId。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.table_area_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2791963816579205标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - tableAreaId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableAreaId。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.assistant_no IS '【说明】明细字段,用于记录事实取值。 【示例】泡芙(明细字段,用于记录事实取值)。 【ODS来源】assistant_cancellation_records - assistantName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.assistant_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】泡芙(名称字段,用于展示与辅助识别)。 【ODS来源】assistant_cancellation_records - assistantName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.charge_minutes_raw IS '【说明】明细字段,用于记录事实取值。 【示例】214明细字段用于记录事实取值。 【ODS来源】assistant_cancellation_records - pdChargeMinutes。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - pdChargeMinutes。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.abolish_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.83(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】assistant_cancellation_records - assistantAbolishAmount。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantAbolishAmount。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.trash_reason IS '【说明】明细字段,用于记录事实取值。 【示例】NULL明细字段用于记录事实取值。 【ODS来源】assistant_cancellation_records - trashReason。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - trashReason。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event.create_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】2025-11-09 19:23:29时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】assistant_cancellation_records - createTime。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - createTime。';
CREATE TABLE IF NOT EXISTS dwd_assistant_trash_event_ex (
assistant_trash_event_id BIGINT,
table_name VARCHAR(64),
table_area_name VARCHAR(64),
PRIMARY KEY (assistant_trash_event_id)
);
COMMENT ON TABLE dwd.dwd_assistant_trash_event_ex IS 'DWD 明细事实表扩展字段表dwd_assistant_trash_event_ex。ODS 来源表billiards_ods.assistant_cancellation_records对应 JSONassistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event_ex.assistant_trash_event_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957675849518789标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - id。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event_ex.table_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】C1名称字段用于展示与辅助识别。 【ODS来源】assistant_cancellation_records - tableName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableName。';
COMMENT ON COLUMN dwd.dwd_assistant_trash_event_ex.table_area_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】C区名称字段用于展示与辅助识别。 【ODS来源】assistant_cancellation_records - tableArea。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableArea。';
-- [已删除] dwd_assistant_trash_event 和 dwd_assistant_trash_event_ex
-- 原因:助教废除链路已清理,废除判断改用 dwd_assistant_service_log_ex.is_trash
-- 参见迁移脚本2026-02-22__drop_assistant_abolish_tables.sql
CREATE TABLE IF NOT EXISTS dwd_member_balance_change (
@@ -1635,6 +1658,7 @@ CREATE TABLE IF NOT EXISTS dwd_member_balance_change_ex (
operator_id BIGINT,
operator_name VARCHAR(64),
principal_data TEXT,
relate_id BIGINT,
PRIMARY KEY (balance_change_id)
);
@@ -1645,6 +1669,7 @@ COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.register_site_name IS '【说
COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.refund_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】member_balance_changes - refund_amount。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - refund_amount。';
COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.operator_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790687322443013标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】member_balance_changes - operator_id。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - operator_id。';
COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.operator_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】收银员:郑丽珊(名称字段,用于展示与辅助识别)。 【ODS来源】member_balance_changes - operator_name。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - operator_name。';
COMMENT ON COLUMN dwd.dwd_member_balance_change_ex.relate_id IS '【说明】关联业务单据 ID指向触发本次余额变动的业务记录如充值单、订单、结算单等按 from_type 不同指向不同表。 【示例】2957881518788421。 【ODS来源】member_balance_changes - relate_id。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - relate_id。';
CREATE TABLE IF NOT EXISTS dwd_groupbuy_redemption (
@@ -1969,7 +1994,7 @@ COMMENT ON COLUMN dwd.dwd_recharge_order_ex.table_id IS '【说明】标识类 I
COMMENT ON COLUMN dwd.dwd_recharge_order_ex.serial_number IS '【说明】数量/时长字段,用于统计与计量。 【示例】NULL数量/时长字段,用于统计与计量)。 【ODS来源】recharge_settlements - serialnumber。 【JSON字段】recharge_settlements.json - $ - serialnumber。';
COMMENT ON COLUMN dwd.dwd_recharge_order_ex.revoke_order_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】NULL标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】recharge_settlements - revokeorderid。 【JSON字段】recharge_settlements.json - $ - revokeorderid。';
COMMENT ON COLUMN dwd.dwd_recharge_order_ex.revoke_order_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】NULL名称字段用于展示与辅助识别。 【ODS来源】recharge_settlements - revokeordername。 【JSON字段】recharge_settlements.json - $ - revokeordername。';
COMMENT ON COLUMN dwd.dwd_recharge_order_ex.revoke_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】NULL时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】recharge_settlements - revoketime。 【JSON字段】recharge_settlements.json - $ - revoketime。';
COMMENT ON COLUMN dwd.dwd_recharge_order_ex.revoke_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【哨兵值处理】上游 API 返回 0001-01-01T00:00:00 表示"未设置"ETL 装载时转为 NULL。 【ODS来源】recharge_settlements - revoketime。 【JSON字段】recharge_settlements.json - $ - revoketime。';
CREATE TABLE IF NOT EXISTS dwd_payment (
@@ -2087,3 +2112,98 @@ COMMENT ON COLUMN dwd.dwd_refund_ex.channel_pay_no IS '【说明】明细字段
-- - 直接原因: settle_list 列已从数据库删除DDL 需同步
-- - 变更摘要: 移除 dwd_settlement_head_ex 表定义中的 settle_list JSONB 列
-- - 风险与验证: 纯 DDL 文档同步;验证:对比 information_schema 确认一致
-- ══════════════════════════════════════════════════════════════
-- dwd_goods_stock_summary库存汇总明细事实表按时间窗口增量加载
-- 来源ods.goods_stock_summary
-- ══════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS dwd.dwd_goods_stock_summary (
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC(18,4),
range_end_stock NUMERIC(18,4),
range_in NUMERIC(18,4),
range_out NUMERIC(18,4),
range_sale NUMERIC(18,4),
range_sale_money NUMERIC(18,2),
range_inventory NUMERIC(18,4),
current_stock NUMERIC(18,4),
site_id BIGINT,
tenant_id BIGINT,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_id, fetched_at)
);
COMMENT ON TABLE dwd.dwd_goods_stock_summary IS '库存汇总明细表事实表。来源ods.goods_stock_summary。按时间窗口增量加载每次采集的库存快照作为一条记录。';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.site_goods_id IS '门店商品 ID主键之一';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.goods_name IS '商品名称';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.goods_unit IS '计量单位';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.goods_category_id IS '一级商品分类 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.goods_category_second_id IS '二级商品分类 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.category_name IS '一级分类名称';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_start_stock IS '期初库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_end_stock IS '期末库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_in IS '入库数量';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_out IS '出库数量';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_sale IS '销售数量';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_sale_money IS '销售金额';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.range_inventory IS '盘点调整量';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.current_stock IS '当前库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.site_id IS '门店 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.tenant_id IS '租户 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_summary.fetched_at IS '采集时间戳(主键之一)';
-- ══════════════════════════════════════════════════════════════
-- dwd_goods_stock_movement库存变动流水事实表按 create_time 增量加载)
-- 来源ods.goods_stock_movements
-- ══════════════════════════════════════════════════════════════
CREATE TABLE IF NOT EXISTS dwd.dwd_goods_stock_movement (
site_goods_stock_id BIGINT NOT NULL,
tenant_id BIGINT,
site_id BIGINT,
site_goods_id BIGINT,
goods_name TEXT,
goods_category_id BIGINT,
goods_second_category_id BIGINT,
unit TEXT,
price NUMERIC(18,4),
stock_type INTEGER,
change_num NUMERIC(18,4),
start_num NUMERIC(18,4),
end_num NUMERIC(18,4),
change_num_a NUMERIC(18,4),
start_num_a NUMERIC(18,4),
end_num_a NUMERIC(18,4),
remark TEXT,
operator_name TEXT,
create_time TIMESTAMPTZ,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_stock_id)
);
COMMENT ON TABLE dwd.dwd_goods_stock_movement IS '库存变动流水表事实表。来源ods.goods_stock_movements。按 create_time 增量加载。';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.site_goods_stock_id IS '库存变动记录 ID主键';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.tenant_id IS '租户 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.site_id IS '门店 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.site_goods_id IS '门店商品 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.goods_name IS '商品名称';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.goods_category_id IS '一级商品分类 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.goods_second_category_id IS '二级商品分类 ID';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.unit IS '计量单位';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.price IS '商品单价';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.stock_type IS '库存变动类型';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.change_num IS '变动数量';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.start_num IS '变动前库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.end_num IS '变动后库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.change_num_a IS '辅助单位变动量';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.start_num_a IS '辅助单位变动前库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.end_num_a IS '辅助单位变动后库存';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.remark IS '备注';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.operator_name IS '操作人';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.create_time IS '变动时间';
COMMENT ON COLUMN dwd.dwd_goods_stock_movement.fetched_at IS '采集时间戳';

View File

@@ -202,7 +202,7 @@ CREATE INDEX idx_cfg_skill_type_course ON dws.cfg_skill_type (course_type_code);
-- 6. dws_assistant_daily_detail - 助教日度业绩明细表
-- 说明:
-- - 以"助教+日期"为粒度,汇总每日业绩明细
-- - 数据来源: dwd_assistant_service_log + dwd_assistant_trash_event排除废除记录)
-- - 数据来源: dwd_assistant_service_log_ex通过 is_trash 字段判断废除记录)
-- - 更新频率: 每小时增量更新
-- - 时间分层: 通过 stat_date 筛选实现近2天/近1月/近3月/全量
-- -----------------------------------------------------------------------------
@@ -249,7 +249,7 @@ CREATE TABLE dws.dws_assistant_daily_detail (
COMMENT ON TABLE dws.dws_assistant_daily_detail IS '助教日度业绩明细:按助教+日期汇总服务次数、时长、金额,支持时间分层查询';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.assistant_level_code IS 'SCD2口径取stat_date当日生效的助教等级';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.trashed_seconds IS '被废除时长来自dwd_assistant_trash_event,影响有效业绩';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.trashed_seconds IS '被废除时长来自dwd_assistant_service_log_ex.is_trash,影响有效业绩';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.room_service_count IS '包厢/房间服务次数';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.room_seconds IS '包厢/房间计费时长(秒)';
COMMENT ON COLUMN dws.dws_assistant_daily_detail.room_hours IS '包厢/房间计费小时数';
@@ -315,7 +315,7 @@ CREATE TABLE dws.dws_assistant_monthly_summary (
-- 元数据
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uk_dws_assistant_monthly UNIQUE (site_id, assistant_id, stat_month)
CONSTRAINT uk_dws_assistant_monthly UNIQUE (site_id, assistant_id, stat_month, assistant_level_code)
);
COMMENT ON TABLE dws.dws_assistant_monthly_summary IS '助教月度业绩汇总:按助教+月份汇总业绩、档位匹配、排名计算';
@@ -398,7 +398,7 @@ CREATE INDEX idx_dws_assistant_customer_member ON dws.dws_assistant_customer_sta
-- -----------------------------------------------------------------------------
-- 9. dws_assistant_salary_calc - 助教工资计算详情表
-- 说明:
-- - 以"助教+月份"为粒度,计算月度工资明细
-- - 以"助教+月份+档位"为粒度,计算月度工资明细
-- - 数据来源: dws_assistant_monthly_summary + cfg_* 配置表
-- - 计算公式来自DWS数据库处理需求.md:
-- * 基础课收入 = 基础课小时数 × (客户支付价格 - 专业课抽成)
@@ -457,7 +457,7 @@ CREATE TABLE dws.dws_assistant_salary_calc (
-- 元数据
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month)
CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month, assistant_level_code)
);
COMMENT ON TABLE dws.dws_assistant_salary_calc IS '助教工资计算详情按DWS数据库处理需求.md公式计算包含课时收入和各类奖金';
@@ -1659,6 +1659,140 @@ COMMENT ON COLUMN dws.dws_index_percentile_history.percentile_5_smoothed IS 'EWM
CREATE INDEX idx_dws_percentile_history ON dws.dws_index_percentile_history (site_id, index_type, calc_time DESC);
-- =============================================================================
-- 第七部分库存维度3张
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 31. dws_goods_stock_daily_summary - 库存日度汇总表
-- 说明:
-- - 以"门店+日期+商品"为粒度,汇总每日库存数据
-- - 数据来源: dwd.dwd_goods_stock_summary按 fetched_at 日期聚合)
-- - 主键: (site_id, stat_date, site_goods_id)
-- - 更新频率: 每日更新
-- -----------------------------------------------------------------------------
DROP TABLE IF EXISTS dws.dws_goods_stock_daily_summary CASCADE;
CREATE TABLE dws.dws_goods_stock_daily_summary (
site_id BIGINT NOT NULL, -- 门店ID
tenant_id BIGINT, -- 租户ID
stat_date DATE NOT NULL, -- 统计日期
site_goods_id BIGINT NOT NULL, -- 门店商品ID
goods_name TEXT, -- 商品名称
goods_unit TEXT, -- 商品单位
goods_category_id BIGINT, -- 商品一级分类ID
goods_category_second_id BIGINT, -- 商品二级分类ID
category_name TEXT, -- 分类名称
range_start_stock NUMERIC, -- 期初库存
range_end_stock NUMERIC, -- 期末库存
range_in NUMERIC, -- 期间入库数量
range_out NUMERIC, -- 期间出库数量
range_sale NUMERIC, -- 期间销售数量
range_sale_money NUMERIC(12,2), -- 期间销售金额(元)
range_inventory NUMERIC, -- 期间盘点数量
current_stock NUMERIC, -- 当前库存
stat_period TEXT NOT NULL DEFAULT 'daily', -- 汇总粒度标识
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_daily_summary IS '库存日度汇总:按门店+日期+商品汇总库存变动,来源 dwd_goods_stock_summary';
COMMENT ON COLUMN dws.dws_goods_stock_daily_summary.stat_date IS '统计日期DWD 采集日期';
COMMENT ON COLUMN dws.dws_goods_stock_daily_summary.range_start_stock IS '期初库存:日度范围内的起始库存';
COMMENT ON COLUMN dws.dws_goods_stock_daily_summary.range_sale_money IS '期间销售金额numeric(12,2) 精度';
COMMENT ON COLUMN dws.dws_goods_stock_daily_summary.stat_period IS '汇总粒度:固定为 daily';
CREATE INDEX idx_dws_goods_stock_daily_date ON dws.dws_goods_stock_daily_summary (stat_date);
CREATE INDEX idx_dws_goods_stock_daily_goods ON dws.dws_goods_stock_daily_summary (site_goods_id, stat_date);
CREATE INDEX idx_dws_goods_stock_daily_site ON dws.dws_goods_stock_daily_summary (site_id, stat_date);
-- -----------------------------------------------------------------------------
-- 32. dws_goods_stock_weekly_summary - 库存周度汇总表
-- 说明:
-- - 以"门店+ISO周+商品"为粒度,汇总每周库存数据
-- - stat_date 存储 ISO 周的周一日期
-- - 数据来源: dwd.dwd_goods_stock_summary按 ISO 周聚合)
-- - 主键: (site_id, stat_date, site_goods_id)
-- -----------------------------------------------------------------------------
DROP TABLE IF EXISTS dws.dws_goods_stock_weekly_summary CASCADE;
CREATE TABLE dws.dws_goods_stock_weekly_summary (
site_id BIGINT NOT NULL, -- 门店ID
tenant_id BIGINT, -- 租户ID
stat_date DATE NOT NULL, -- 统计日期ISO 周一)
site_goods_id BIGINT NOT NULL, -- 门店商品ID
goods_name TEXT, -- 商品名称
goods_unit TEXT, -- 商品单位
goods_category_id BIGINT, -- 商品一级分类ID
goods_category_second_id BIGINT, -- 商品二级分类ID
category_name TEXT, -- 分类名称
range_start_stock NUMERIC, -- 周初库存
range_end_stock NUMERIC, -- 周末库存
range_in NUMERIC, -- 周间入库数量
range_out NUMERIC, -- 周间出库数量
range_sale NUMERIC, -- 周间销售数量
range_sale_money NUMERIC(12,2), -- 周间销售金额(元)
range_inventory NUMERIC, -- 周间盘点数量
current_stock NUMERIC, -- 当前库存
stat_period TEXT NOT NULL DEFAULT 'weekly', -- 汇总粒度标识
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_weekly_summary IS '库存周度汇总:按门店+ISO周+商品汇总库存变动stat_date 为周一日期';
COMMENT ON COLUMN dws.dws_goods_stock_weekly_summary.stat_date IS '统计日期ISO 周的周一日期';
COMMENT ON COLUMN dws.dws_goods_stock_weekly_summary.range_start_stock IS '周初库存:该周范围内的起始库存';
COMMENT ON COLUMN dws.dws_goods_stock_weekly_summary.stat_period IS '汇总粒度:固定为 weekly';
CREATE INDEX idx_dws_goods_stock_weekly_date ON dws.dws_goods_stock_weekly_summary (stat_date);
CREATE INDEX idx_dws_goods_stock_weekly_goods ON dws.dws_goods_stock_weekly_summary (site_goods_id, stat_date);
CREATE INDEX idx_dws_goods_stock_weekly_site ON dws.dws_goods_stock_weekly_summary (site_id, stat_date);
-- -----------------------------------------------------------------------------
-- 33. dws_goods_stock_monthly_summary - 库存月度汇总表
-- 说明:
-- - 以"门店+自然月+商品"为粒度,汇总每月库存数据
-- - stat_date 存储月首日期(如 2026-01-01
-- - 数据来源: dwd.dwd_goods_stock_summary按自然月聚合
-- - 主键: (site_id, stat_date, site_goods_id)
-- -----------------------------------------------------------------------------
DROP TABLE IF EXISTS dws.dws_goods_stock_monthly_summary CASCADE;
CREATE TABLE dws.dws_goods_stock_monthly_summary (
site_id BIGINT NOT NULL, -- 门店ID
tenant_id BIGINT, -- 租户ID
stat_date DATE NOT NULL, -- 统计日期(月首日期)
site_goods_id BIGINT NOT NULL, -- 门店商品ID
goods_name TEXT, -- 商品名称
goods_unit TEXT, -- 商品单位
goods_category_id BIGINT, -- 商品一级分类ID
goods_category_second_id BIGINT, -- 商品二级分类ID
category_name TEXT, -- 分类名称
range_start_stock NUMERIC, -- 月初库存
range_end_stock NUMERIC, -- 月末库存
range_in NUMERIC, -- 月间入库数量
range_out NUMERIC, -- 月间出库数量
range_sale NUMERIC, -- 月间销售数量
range_sale_money NUMERIC(12,2), -- 月间销售金额(元)
range_inventory NUMERIC, -- 月间盘点数量
current_stock NUMERIC, -- 当前库存
stat_period TEXT NOT NULL DEFAULT 'monthly', -- 汇总粒度标识
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE dws.dws_goods_stock_monthly_summary IS '库存月度汇总:按门店+自然月+商品汇总库存变动stat_date 为月首日期';
COMMENT ON COLUMN dws.dws_goods_stock_monthly_summary.stat_date IS '统计日期:月首日期,如 2026-01-01';
COMMENT ON COLUMN dws.dws_goods_stock_monthly_summary.range_start_stock IS '月初库存:该月范围内的起始库存';
COMMENT ON COLUMN dws.dws_goods_stock_monthly_summary.stat_period IS '汇总粒度:固定为 monthly';
CREATE INDEX idx_dws_goods_stock_monthly_date ON dws.dws_goods_stock_monthly_summary (stat_date);
CREATE INDEX idx_dws_goods_stock_monthly_goods ON dws.dws_goods_stock_monthly_summary (site_goods_id, stat_date);
CREATE INDEX idx_dws_goods_stock_monthly_site ON dws.dws_goods_stock_monthly_summary (site_id, stat_date);
-- =============================================================================
-- 完成提示
-- =============================================================================
@@ -1671,5 +1805,6 @@ CREATE INDEX idx_dws_percentile_history ON dws.dws_index_percentile_history (sit
-- - 7张财务维度表dws_finance_* + dws_assistant_finance_* + dws_platform_*
-- - 1张订单汇总表dws_order_summary
-- - 1张分位点历史表dws_index_percentile_history
-- - 3张库存汇总表dws_goods_stock_daily/weekly/monthly_summary
-- - 1个召回优先级视图v_member_recall_priority
-- - 2个辅助函数get_time_window, get_comparison_window

View File

@@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS ods.member_profiles (
person_tenant_org_name TEXT,
recharge_money_sum NUMERIC(18,2),
register_source TEXT,
birthday DATE,
content_hash TEXT NOT NULL,
source_file TEXT,
source_endpoint TEXT,
@@ -52,6 +53,7 @@ COMMENT ON COLUMN ods.member_profiles.source_file IS '【说明】ETL 元数据
COMMENT ON COLUMN ods.member_profiles.source_endpoint IS '【说明】ETL 元数据:采集来源(接口/文件路径),用于数据追溯。 【示例】export/test-json-doc/member_profiles.jsonETL 元数据:采集来源(接口/文件路径),用于数据追溯)。 【JSON字段】member_profiles.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.member_profiles.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】member_profiles.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.member_profiles.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】member_profiles.json - data.tenantMemberInfos - $。';
COMMENT ON COLUMN ods.member_profiles.birthday IS '【说明】会员生日,来源:上游 API payload 中的 birthday 字段。 【JSON字段】member_profiles.json - data.tenantMemberInfos - birthday。';
CREATE TABLE IF NOT EXISTS ods.member_balance_changes (
@@ -572,47 +574,10 @@ COMMENT ON COLUMN ods.settlement_records.fetched_at IS '【说明】ETL 元数
COMMENT ON COLUMN ods.settlement_records.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】settlement_records.json - $ - $。';
CREATE TABLE IF NOT EXISTS ods.assistant_cancellation_records (
id BIGINT,
siteId BIGINT,
siteProfile JSONB,
assistantName TEXT,
assistantAbolishAmount NUMERIC(18,2),
assistantOn INT,
pdChargeMinutes INT,
tableAreaId BIGINT,
tableArea TEXT,
tableId BIGINT,
tableName TEXT,
trashReason TEXT,
createTime TIMESTAMP,
tenant_id BIGINT,
content_hash TEXT NOT NULL,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (id, content_hash)
);
-- [已删除] assistant_cancellation_records
-- 原因:助教废除链路已清理,废除判断改用 dwd_assistant_service_log_ex.is_trash
-- 参见迁移脚本2026-02-22__drop_assistant_abolish_tables.sql
COMMENT ON TABLE ods.assistant_cancellation_records IS 'ODS 原始明细表:助教作废/取消记录。来源export/test-json-doc/assistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。字段以导出原样为主ETL 补充 source_file/source_endpoint/fetched_at并保留 payload 为原始记录快照。';
COMMENT ON COLUMN ods.assistant_cancellation_records.id IS '【说明】本表主键 ID用于唯一标识一条记录。 【示例】2957675849518789本表主键 ID用于唯一标识一条记录。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN ods.assistant_cancellation_records.siteId IS '【说明】门店 ID即该废除记录所在门店。 【示例】2790685415443269用于门店 ID即该废除记录所在门店。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteId。';
COMMENT ON COLUMN ods.assistant_cancellation_records.siteProfile IS '【说明】门店信息快照。 【示例】{"id": 2790685415443269, "org_id": 2790684179467077, "shop_name": "朗朗桌球", "avatar": "https://oss.ficoo.vip/admin/hXcE4E…用于门店信息快照。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteProfile。';
COMMENT ON COLUMN ods.assistant_cancellation_records.assistantName IS '【说明】助教姓名/对外展示名称。 【示例】泡芙(用于助教姓名/对外展示名称)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN ods.assistant_cancellation_records.assistantAbolishAmount IS '【说明】与“助教废除”关联的金额字段。 【示例】5.83(用于与“助教废除”关联的金额字段)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantAbolishAmount。';
COMMENT ON COLUMN ods.assistant_cancellation_records.assistantOn IS '【说明】助教编号(工号/序号)。 【示例】27用于助教编号工号/序号))。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantOn。';
COMMENT ON COLUMN ods.assistant_cancellation_records.pdChargeMinutes IS '【说明】“已发生的计费时长(分钟)”,即这次助教服务在被废除前已经累计了多少分钟。 【示例】214用于“已发生的计费时长分钟即这次助教服务在被废除前已经累计了多少分钟。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - pdChargeMinutes。';
COMMENT ON COLUMN ods.assistant_cancellation_records.tableAreaId IS '【说明】台桌所在区域 ID。 【示例】2791963816579205用于台桌所在区域 ID。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableAreaId。';
COMMENT ON COLUMN ods.assistant_cancellation_records.tableArea IS '【说明】台桌所属区域名称。 【示例】C区用于台桌所属区域名称。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableArea。';
COMMENT ON COLUMN ods.assistant_cancellation_records.tableId IS '【说明】球台/桌子的 ID。 【示例】2793016660660357用于球台/桌子的 ID。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableId。';
COMMENT ON COLUMN ods.assistant_cancellation_records.tableName IS '【说明】台桌名称/编号,供人阅读。 【示例】C1用于台桌名称/编号,供人阅读)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableName。';
COMMENT ON COLUMN ods.assistant_cancellation_records.trashReason IS '【说明】用于记录“废除原因”的文本描述,例如“顾客临时有事取消”“录入错误”“更换助教”等。 【示例】NULL用于记录“废除原因”的文本描述例如“顾客临时有事取消”“录入错误”“更换助教”等。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - trashReason。';
COMMENT ON COLUMN ods.assistant_cancellation_records.createTime IS '【说明】这条“助教废除记录”被创建的时间,即系统正式记录“废除”操作的时刻。 【示例】2025-11-09 19:23:29用于这条“助教废除记录”被创建的时间即系统正式记录“废除”操作的时刻。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - createTime。';
COMMENT ON COLUMN ods.assistant_cancellation_records.source_file IS '【说明】ETL 元数据:原始导出文件名,用于数据追溯。 【示例】assistant_cancellation_records.jsonETL 元数据:原始导出文件名,用于数据追溯)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.assistant_cancellation_records.source_endpoint IS '【说明】ETL 元数据:采集来源(接口/文件路径),用于数据追溯。 【示例】export/test-json-doc/assistant_cancellation_records.jsonETL 元数据:采集来源(接口/文件路径),用于数据追溯)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.assistant_cancellation_records.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.assistant_cancellation_records.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - $。';
CREATE TABLE IF NOT EXISTS ods.assistant_accounts_master (
@@ -1730,98 +1695,6 @@ COMMENT ON COLUMN ods.group_buy_redemption_records.source_endpoint IS '【说明
COMMENT ON COLUMN ods.group_buy_redemption_records.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】group_buy_redemption_records.json - ETL元数据 - 无。';
CREATE TABLE IF NOT EXISTS ods.settlement_ticket_details (
orderSettleId BIGINT,
actualPayment NUMERIC(18,2),
adjustAmount NUMERIC(18,2),
assistantManualDiscount NUMERIC(18,2),
balanceAmount NUMERIC(18,2),
cashierName TEXT,
consumeMoney NUMERIC(18,2),
couponAmount NUMERIC(18,2),
deliveryAddress TEXT,
deliveryFee NUMERIC(18,2),
ledgerAmount NUMERIC(18,2),
memberDeductAmount NUMERIC(18,2),
memberOfferAmount NUMERIC(18,2),
onlineReturnAmount NUMERIC(18,2),
orderRemark TEXT,
orderSettleNumber BIGINT,
payMemberBalance NUMERIC(18,2),
payTime TIMESTAMP,
paymentMethod INT,
pointDiscountCost NUMERIC(18,2),
pointDiscountPrice NUMERIC(18,2),
prepayMoney NUMERIC(18,2),
refundAmount NUMERIC(18,2),
returnGoodsAmount NUMERIC(18,2),
rewardName TEXT,
settleType TEXT,
siteAddress TEXT,
siteBusinessTel TEXT,
siteId BIGINT,
siteName TEXT,
tenantId BIGINT,
tenantName TEXT,
ticketCustomContent TEXT,
ticketRemark TEXT,
voucherMoney NUMERIC(18,2),
memberProfile JSONB,
orderItem JSONB,
tenantMemberCardLogs JSONB,
payload JSONB NOT NULL,
content_hash TEXT NOT NULL,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (orderSettleId, content_hash)
);
COMMENT ON TABLE ods.settlement_ticket_details IS 'ODS 原始明细表结算小票明细。来源export/test-json-doc/settlement_ticket_details.json分析settlement_ticket_details-Analysis.md。字段以导出原样为主ETL 补充 source_file/source_endpoint/fetched_at并保留 payload 为原始记录快照。';
COMMENT ON COLUMN ods.settlement_ticket_details.orderSettleId IS '【说明】结算单 ID和顶层字段相同再次冗余。 【示例】2957922914357125用于结算单 ID和顶层字段相同再次冗余。 【JSON字段】settlement_ticket_details.json - $ - orderSettleId。';
COMMENT ON COLUMN ods.settlement_ticket_details.actualPayment IS '【说明】本单实际支付金额总和(顾客本次实际付出:现金 + 线上 + 会员余额等)。 【示例】NULL用于本单实际支付金额总和顾客本次实际付出现金 + 线上 + 会员余额等))。 【JSON字段】settlement_ticket_details.json - $ - actualPayment。';
COMMENT ON COLUMN ods.settlement_ticket_details.adjustAmount IS '【说明】人工调价/整单调整金额(例如手工改价、折扣调整),是所有类型的手工调整合计。 【示例】NULL用于人工调价/整单调整金额(例如手工改价、折扣调整),是所有类型的手工调整合计)。 【JSON字段】settlement_ticket_details.json - $ - adjustAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.assistantManualDiscount IS '【说明】针对“助教项目”的人工减免金额汇总(整单维度)。 【示例】NULL用于针对“助教项目”的人工减免金额汇总整单维度。 【JSON字段】settlement_ticket_details.json - $ - assistantManualDiscount。';
COMMENT ON COLUMN ods.settlement_ticket_details.balanceAmount IS '【说明】本单通过“会员余额/储值卡”支付的金额(从余额中扣除的总额)。 【示例】NULL用于本单通过“会员余额/储值卡”支付的金额(从余额中扣除的总额))。 【JSON字段】settlement_ticket_details.json - $ - balanceAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.cashierName IS '【说明】本单结算操作员名称(带角色前缀文字)。 【示例】NULL用于本单结算操作员名称带角色前缀文字。 【JSON字段】settlement_ticket_details.json - $ - cashierName。';
COMMENT ON COLUMN ods.settlement_ticket_details.consumeMoney IS '【说明】本单“消费金额总计”(原价层面),即台费 + 商品 + 助教 + 服务等消费项目的金额总和(未扣除各类优惠)。 【示例】NULL用于本单“消费金额总计”原价层面即台费 + 商品 + 助教 + 服务等消费项目的金额总和(未扣除各类优惠))。 【JSON字段】settlement_ticket_details.json - $ - consumeMoney。';
COMMENT ON COLUMN ods.settlement_ticket_details.couponAmount IS '【说明】本单由优惠券抵扣的金额汇总。 【示例】NULL用于本单由优惠券抵扣的金额汇总。 【JSON字段】settlement_ticket_details.json - $ - couponAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.deliveryAddress IS '【说明】配送地址(若存在外送业务时使用)。 【示例】NULL用于配送地址若存在外送业务时使用。 【JSON字段】settlement_ticket_details.json - $ - deliveryAddress。';
COMMENT ON COLUMN ods.settlement_ticket_details.deliveryFee IS '【说明】配送费金额(如果支持外送业务)。 【示例】NULL用于配送费金额如果支持外送业务。 【JSON字段】settlement_ticket_details.json - $ - deliveryFee。';
COMMENT ON COLUMN ods.settlement_ticket_details.ledgerAmount IS '【说明】商品小计金额(通常 = 单价 × 数量,未考虑其他折扣)。 【示例】NULL用于商品小计金额通常 = 单价 × 数量,未考虑其他折扣))。 【JSON字段】settlement_ticket_details.json - $ - ledgerAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.memberDeductAmount IS '【说明】会员抵扣的某种数量或金额(例如积分抵现金额、次卡次数抵扣等),当前数据未启用。 【示例】NULL用于会员抵扣的某种数量或金额例如积分抵现金额、次卡次数抵扣等当前数据未启用。 【JSON字段】settlement_ticket_details.json - $ - memberDeductAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.memberOfferAmount IS '【说明】由“会员权益/折扣”产生的优惠金额总计(整单维度)。 【示例】NULL用于由“会员权益/折扣”产生的优惠金额总计(整单维度))。 【JSON字段】settlement_ticket_details.json - $ - memberOfferAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.onlineReturnAmount IS '【说明】本单通过线上支付渠道退回的金额(如微信/支付宝退款)。 【示例】NULL用于本单通过线上支付渠道退回的金额如微信/支付宝退款))。 【JSON字段】settlement_ticket_details.json - $ - onlineReturnAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.orderRemark IS '【说明】订单备注,由收银员录入,用于记录与本单相关的特殊说明。 【示例】NULL订单备注由收银员录入用于记录与本单相关的特殊说明。 【JSON字段】settlement_ticket_details.json - $ - orderRemark。';
COMMENT ON COLUMN ods.settlement_ticket_details.orderSettleNumber IS '【说明】结算单编号(与 ID 独立的一套编号体系,如流水号)。 【示例】NULL用于结算单编号与 ID 独立的一套编号体系,如流水号))。 【JSON字段】settlement_ticket_details.json - $ - orderSettleNumber。';
COMMENT ON COLUMN ods.settlement_ticket_details.payMemberBalance IS '【说明】使用会员余额支付的金额,用于区分与 balanceAmount 的不同维度(如“本次支付使用余额部分”与“余额本身变化”等),当前未实际使用。 【示例】NULL使用会员余额支付的金额用于区分与 balanceAmount 的不同维度(如“本次支付使用余额部分”与“余额本身变化”等),当前未实际使用)。 【JSON字段】settlement_ticket_details.json - $ - payMemberBalance。';
COMMENT ON COLUMN ods.settlement_ticket_details.payTime IS '【说明】本单最终支付成功时间。 【示例】NULL用于本单最终支付成功时间。 【JSON字段】settlement_ticket_details.json - $ - payTime。';
COMMENT ON COLUMN ods.settlement_ticket_details.paymentMethod IS '【说明】结算主支付方式编码(汇总视角)。 【示例】NULL用于结算主支付方式编码汇总视角。 【JSON字段】settlement_ticket_details.json - $ - paymentMethod。';
COMMENT ON COLUMN ods.settlement_ticket_details.pointDiscountCost IS '【说明】积分抵扣对应的成本金额(成本侧)。 【示例】NULL用于积分抵扣对应的成本金额成本侧。 【JSON字段】settlement_ticket_details.json - $ - pointDiscountCost。';
COMMENT ON COLUMN ods.settlement_ticket_details.pointDiscountPrice IS '【说明】积分抵扣对应的金额(售价侧)。 【示例】NULL用于积分抵扣对应的金额售价侧。 【JSON字段】settlement_ticket_details.json - $ - pointDiscountPrice。';
COMMENT ON COLUMN ods.settlement_ticket_details.prepayMoney IS '【说明】预付金/定金在本单中使用的金额。 【示例】NULL用于预付金/定金在本单中使用的金额)。 【JSON字段】settlement_ticket_details.json - $ - prepayMoney。';
COMMENT ON COLUMN ods.settlement_ticket_details.refundAmount IS '【说明】本单涉及的退款金额(汇总)。 【示例】NULL用于本单涉及的退款金额汇总。 【JSON字段】settlement_ticket_details.json - $ - refundAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.returnGoodsAmount IS '【说明】本单涉及的退货金额汇总。 【示例】NULL用于本单涉及的退货金额汇总。 【JSON字段】settlement_ticket_details.json - $ - returnGoodsAmount。';
COMMENT ON COLUMN ods.settlement_ticket_details.rewardName IS '【说明】用于标识本单适用的激励方案名称,可能用于内部绩效或活动名称展示。 【示例】NULL用于标识本单适用的激励方案名称可能用于内部绩效或活动名称展示。 【JSON字段】settlement_ticket_details.json - $ - rewardName。';
COMMENT ON COLUMN ods.settlement_ticket_details.settleType IS '【说明】结算类型字符串标识。 【示例】NULL用于结算类型字符串标识。 【JSON字段】settlement_ticket_details.json - $ - settleType。';
COMMENT ON COLUMN ods.settlement_ticket_details.siteAddress IS '【说明】门店地址(详细地址)。 【示例】NULL用于门店地址详细地址。 【JSON字段】settlement_ticket_details.json - $ - siteAddress。';
COMMENT ON COLUMN ods.settlement_ticket_details.siteBusinessTel IS '【说明】门店电话。 【示例】NULL用于门店电话。 【JSON字段】settlement_ticket_details.json - $ - siteBusinessTel。';
COMMENT ON COLUMN ods.settlement_ticket_details.siteId IS '【说明】门店 ID。 【示例】NULL用于门店 ID。 【JSON字段】settlement_ticket_details.json - $ - siteId。';
COMMENT ON COLUMN ods.settlement_ticket_details.siteName IS '【说明】门店名称,如“朗朗桌球”。 【示例】NULL用于门店名称如“朗朗桌球”。 【JSON字段】settlement_ticket_details.json - $ - siteName。';
COMMENT ON COLUMN ods.settlement_ticket_details.tenantId IS '【说明】租户 / 商户 ID品牌维度。 【示例】NULL用于租户 / 商户 ID品牌维度。 【JSON字段】settlement_ticket_details.json - $ - tenantId。';
COMMENT ON COLUMN ods.settlement_ticket_details.tenantName IS '【说明】租户名称,如“朗朗桌球”。 【示例】NULL用于租户名称如“朗朗桌球”。 【JSON字段】settlement_ticket_details.json - $ - tenantName。';
COMMENT ON COLUMN ods.settlement_ticket_details.ticketCustomContent IS '【说明】自定义小票内容,如商家自定义宣传语、条款等。 【示例】NULL用于自定义小票内容如商家自定义宣传语、条款等。 【JSON字段】settlement_ticket_details.json - $ - ticketCustomContent。';
COMMENT ON COLUMN ods.settlement_ticket_details.ticketRemark IS '【说明】小票备注内容,可用于打印在小票底部或顶部(例如活动说明、特别提示)。 【示例】NULL小票备注内容可用于打印在小票底部或顶部例如活动说明、特别提示。 【JSON字段】settlement_ticket_details.json - $ - ticketRemark。';
COMMENT ON COLUMN ods.settlement_ticket_details.voucherMoney IS '【说明】代金券类金额字段(可能用于某类“代金券余额”或“券面值”记录)。 【示例】NULL代金券类金额字段可能用于某类“代金券余额”或“券面值”记录。 【JSON字段】settlement_ticket_details.json - $ - voucherMoney。';
COMMENT ON COLUMN ods.settlement_ticket_details.memberProfile IS '【说明】不是会员卡主键,而是本次结账时的会员信息快照。 【示例】NULL用于不是会员卡主键而是本次结账时的会员信息快照。 【JSON字段】settlement_ticket_details.json - $ - memberProfile。';
COMMENT ON COLUMN ods.settlement_ticket_details.orderItem IS '【说明】本次结算对应的“订单明细列表”,这部分是连接“台费流水 / 商品出库 / 券使用”等多个子领域的关键结构。 【示例】NULL用于本次结算对应的“订单明细列表”这部分是连接“台费流水 / 商品出库 / 券使用”等多个子领域的关键结构)。 【JSON字段】settlement_ticket_details.json - $ - orderItem。';
COMMENT ON COLUMN ods.settlement_ticket_details.tenantMemberCardLogs IS '【说明】来自 JSON 导出的原始字段,用于保留业务取值。 【示例】NULL来自 JSON 导出的原始字段,用于保留业务取值)。 【JSON字段】settlement_ticket_details.json - $ - tenantMemberCardLogs。';
COMMENT ON COLUMN ods.settlement_ticket_details.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】settlement_ticket_details.json - $ - $。';
COMMENT ON COLUMN ods.settlement_ticket_details.source_file IS '【说明】ETL 元数据:原始导出文件名,用于数据追溯。 【示例】settlement_ticket_details.jsonETL 元数据:原始导出文件名,用于数据追溯)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.settlement_ticket_details.source_endpoint IS '【说明】ETL 元数据:采集来源(接口/文件路径),用于数据追溯。 【示例】export/test-json-doc/settlement_ticket_details.jsonETL 元数据:采集来源(接口/文件路径),用于数据追溯)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
COMMENT ON COLUMN ods.settlement_ticket_details.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
CREATE TABLE IF NOT EXISTS ods.store_goods_master (
id BIGINT,
tenant_id BIGINT,
@@ -1870,6 +1743,7 @@ CREATE TABLE IF NOT EXISTS ods.store_goods_master (
update_time TIMESTAMP,
commodity_code TEXT,
not_sale INTEGER,
time_slot_sale INTEGER, -- CHANGE 2026-02-21 | 新增分时段销售标记API 返回但此前未收录)
payload JSONB NOT NULL,
content_hash TEXT NOT NULL,
source_file TEXT,
@@ -1878,6 +1752,7 @@ CREATE TABLE IF NOT EXISTS ods.store_goods_master (
PRIMARY KEY (id, content_hash)
);
COMMENT ON COLUMN ods.store_goods_master.time_slot_sale IS '【说明】分时段销售标记API 返回值,当前观测全部为 2。 【示例】2。 【JSON字段】store_goods_master.json - data.orderGoodsList - time_slot_sale。';
COMMENT ON TABLE ods.store_goods_master IS 'ODS 原始明细表门店商品主数据。来源export/test-json-doc/store_goods_master.json分析store_goods_master-Analysis.md。字段以导出原样为主ETL 补充 source_file/source_endpoint/fetched_at并保留 payload 为原始记录快照。';
COMMENT ON COLUMN ods.store_goods_master.id IS '【说明】门店商品 ID门店维度的商品主键。 【示例】2793025851560005用于门店商品 ID门店维度的商品主键。 【JSON字段】store_goods_master.json - data.orderGoodsList - id。';
COMMENT ON COLUMN ods.store_goods_master.tenant_id IS '【说明】租户/品牌 ID。 【示例】2790683160709957用于租户/品牌 ID。 【JSON字段】store_goods_master.json - data.orderGoodsList - tenant_id。';
@@ -2069,8 +1944,7 @@ CREATE INDEX IF NOT EXISTS idx_ods_recharge_settlements_latest
CREATE INDEX IF NOT EXISTS idx_ods_settlement_records_latest
ON ods.settlement_records (id, fetched_at DESC);
CREATE INDEX IF NOT EXISTS idx_ods_assistant_cancellation_records_latest
ON ods.assistant_cancellation_records (id, fetched_at DESC);
-- [已删除] idx_ods_assistant_cancellation_records_latest(随表一起移除)
CREATE INDEX IF NOT EXISTS idx_ods_assistant_accounts_master_latest
ON ods.assistant_accounts_master (id, fetched_at DESC);
@@ -2114,9 +1988,6 @@ CREATE INDEX IF NOT EXISTS idx_ods_group_buy_packages_latest
CREATE INDEX IF NOT EXISTS idx_ods_group_buy_redemption_records_latest
ON ods.group_buy_redemption_records (id, fetched_at DESC);
CREATE INDEX IF NOT EXISTS idx_ods_settlement_ticket_details_latest
ON ods.settlement_ticket_details (orderSettleId, fetched_at DESC);
CREATE INDEX IF NOT EXISTS idx_ods_store_goods_master_latest
ON ods.store_goods_master (id, fetched_at DESC);

View File

@@ -572,47 +572,10 @@ COMMENT ON COLUMN billiards_ods.settlement_records.fetched_at IS '【说明】ET
COMMENT ON COLUMN billiards_ods.settlement_records.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】settlement_records.json - $ - $。';
CREATE TABLE IF NOT EXISTS billiards_ods.assistant_cancellation_records (
id BIGINT,
siteId BIGINT,
siteProfile JSONB,
assistantName TEXT,
assistantAbolishAmount NUMERIC(18,2),
assistantOn INT,
pdChargeMinutes INT,
tableAreaId BIGINT,
tableArea TEXT,
tableId BIGINT,
tableName TEXT,
trashReason TEXT,
createTime TIMESTAMP,
tenant_id BIGINT,
content_hash TEXT NOT NULL,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
payload JSONB NOT NULL,
PRIMARY KEY (id, content_hash)
);
-- [已删除] assistant_cancellation_records
-- 原因:助教废除链路已清理,废除判断改用 dwd_assistant_service_log_ex.is_trash
-- 参见迁移脚本2026-02-22__drop_assistant_abolish_tables.sql
COMMENT ON TABLE billiards_ods.assistant_cancellation_records IS 'ODS 原始明细表:助教作废/取消记录。来源export/test-json-doc/assistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。字段以导出原样为主ETL 补充 source_file/source_endpoint/fetched_at并保留 payload 为原始记录快照。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.id IS '【说明】本表主键 ID用于唯一标识一条记录。 【示例】2957675849518789本表主键 ID用于唯一标识一条记录。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.siteId IS '【说明】门店 ID即该废除记录所在门店。 【示例】2790685415443269用于门店 ID即该废除记录所在门店。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteId。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.siteProfile IS '【说明】门店信息快照。 【示例】{"id": 2790685415443269, "org_id": 2790684179467077, "shop_name": "朗朗桌球", "avatar": "https://oss.ficoo.vip/admin/hXcE4E…用于门店信息快照。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteProfile。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.assistantName IS '【说明】助教姓名/对外展示名称。 【示例】泡芙(用于助教姓名/对外展示名称)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.assistantAbolishAmount IS '【说明】与“助教废除”关联的金额字段。 【示例】5.83(用于与“助教废除”关联的金额字段)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantAbolishAmount。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.assistantOn IS '【说明】助教编号(工号/序号)。 【示例】27用于助教编号工号/序号))。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantOn。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.pdChargeMinutes IS '【说明】“已发生的计费时长(分钟)”,即这次助教服务在被废除前已经累计了多少分钟。 【示例】214用于“已发生的计费时长分钟即这次助教服务在被废除前已经累计了多少分钟。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - pdChargeMinutes。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.tableAreaId IS '【说明】台桌所在区域 ID。 【示例】2791963816579205用于台桌所在区域 ID。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableAreaId。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.tableArea IS '【说明】台桌所属区域名称。 【示例】C区用于台桌所属区域名称。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableArea。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.tableId IS '【说明】球台/桌子的 ID。 【示例】2793016660660357用于球台/桌子的 ID。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableId。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.tableName IS '【说明】台桌名称/编号,供人阅读。 【示例】C1用于台桌名称/编号,供人阅读)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableName。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.trashReason IS '【说明】用于记录“废除原因”的文本描述,例如“顾客临时有事取消”“录入错误”“更换助教”等。 【示例】NULL用于记录“废除原因”的文本描述例如“顾客临时有事取消”“录入错误”“更换助教”等。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - trashReason。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.createTime IS '【说明】这条“助教废除记录”被创建的时间,即系统正式记录“废除”操作的时刻。 【示例】2025-11-09 19:23:29用于这条“助教废除记录”被创建的时间即系统正式记录“废除”操作的时刻。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - createTime。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.source_file IS '【说明】ETL 元数据:原始导出文件名,用于数据追溯。 【示例】assistant_cancellation_records.jsonETL 元数据:原始导出文件名,用于数据追溯)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.source_endpoint IS '【说明】ETL 元数据:采集来源(接口/文件路径),用于数据追溯。 【示例】export/test-json-doc/assistant_cancellation_records.jsonETL 元数据:采集来源(接口/文件路径),用于数据追溯)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】assistant_cancellation_records.json - ETL元数据 - 无。';
COMMENT ON COLUMN billiards_ods.assistant_cancellation_records.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - $。';
CREATE TABLE IF NOT EXISTS billiards_ods.assistant_accounts_master (
@@ -1730,98 +1693,6 @@ COMMENT ON COLUMN billiards_ods.group_buy_redemption_records.source_endpoint IS
COMMENT ON COLUMN billiards_ods.group_buy_redemption_records.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】group_buy_redemption_records.json - ETL元数据 - 无。';
CREATE TABLE IF NOT EXISTS billiards_ods.settlement_ticket_details (
orderSettleId BIGINT,
actualPayment NUMERIC(18,2),
adjustAmount NUMERIC(18,2),
assistantManualDiscount NUMERIC(18,2),
balanceAmount NUMERIC(18,2),
cashierName TEXT,
consumeMoney NUMERIC(18,2),
couponAmount NUMERIC(18,2),
deliveryAddress TEXT,
deliveryFee NUMERIC(18,2),
ledgerAmount NUMERIC(18,2),
memberDeductAmount NUMERIC(18,2),
memberOfferAmount NUMERIC(18,2),
onlineReturnAmount NUMERIC(18,2),
orderRemark TEXT,
orderSettleNumber BIGINT,
payMemberBalance NUMERIC(18,2),
payTime TIMESTAMP,
paymentMethod INT,
pointDiscountCost NUMERIC(18,2),
pointDiscountPrice NUMERIC(18,2),
prepayMoney NUMERIC(18,2),
refundAmount NUMERIC(18,2),
returnGoodsAmount NUMERIC(18,2),
rewardName TEXT,
settleType TEXT,
siteAddress TEXT,
siteBusinessTel TEXT,
siteId BIGINT,
siteName TEXT,
tenantId BIGINT,
tenantName TEXT,
ticketCustomContent TEXT,
ticketRemark TEXT,
voucherMoney NUMERIC(18,2),
memberProfile JSONB,
orderItem JSONB,
tenantMemberCardLogs JSONB,
payload JSONB NOT NULL,
content_hash TEXT NOT NULL,
source_file TEXT,
source_endpoint TEXT,
fetched_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (orderSettleId, content_hash)
);
COMMENT ON TABLE billiards_ods.settlement_ticket_details IS 'ODS 原始明细表结算小票明细。来源export/test-json-doc/settlement_ticket_details.json分析settlement_ticket_details-Analysis.md。字段以导出原样为主ETL 补充 source_file/source_endpoint/fetched_at并保留 payload 为原始记录快照。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.orderSettleId IS '【说明】结算单 ID和顶层字段相同再次冗余。 【示例】2957922914357125用于结算单 ID和顶层字段相同再次冗余。 【JSON字段】settlement_ticket_details.json - $ - orderSettleId。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.actualPayment IS '【说明】本单实际支付金额总和(顾客本次实际付出:现金 + 线上 + 会员余额等)。 【示例】NULL用于本单实际支付金额总和顾客本次实际付出现金 + 线上 + 会员余额等))。 【JSON字段】settlement_ticket_details.json - $ - actualPayment。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.adjustAmount IS '【说明】人工调价/整单调整金额(例如手工改价、折扣调整),是所有类型的手工调整合计。 【示例】NULL用于人工调价/整单调整金额(例如手工改价、折扣调整),是所有类型的手工调整合计)。 【JSON字段】settlement_ticket_details.json - $ - adjustAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.assistantManualDiscount IS '【说明】针对“助教项目”的人工减免金额汇总(整单维度)。 【示例】NULL用于针对“助教项目”的人工减免金额汇总整单维度。 【JSON字段】settlement_ticket_details.json - $ - assistantManualDiscount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.balanceAmount IS '【说明】本单通过“会员余额/储值卡”支付的金额(从余额中扣除的总额)。 【示例】NULL用于本单通过“会员余额/储值卡”支付的金额(从余额中扣除的总额))。 【JSON字段】settlement_ticket_details.json - $ - balanceAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.cashierName IS '【说明】本单结算操作员名称(带角色前缀文字)。 【示例】NULL用于本单结算操作员名称带角色前缀文字。 【JSON字段】settlement_ticket_details.json - $ - cashierName。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.consumeMoney IS '【说明】本单“消费金额总计”(原价层面),即台费 + 商品 + 助教 + 服务等消费项目的金额总和(未扣除各类优惠)。 【示例】NULL用于本单“消费金额总计”原价层面即台费 + 商品 + 助教 + 服务等消费项目的金额总和(未扣除各类优惠))。 【JSON字段】settlement_ticket_details.json - $ - consumeMoney。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.couponAmount IS '【说明】本单由优惠券抵扣的金额汇总。 【示例】NULL用于本单由优惠券抵扣的金额汇总。 【JSON字段】settlement_ticket_details.json - $ - couponAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.deliveryAddress IS '【说明】配送地址(若存在外送业务时使用)。 【示例】NULL用于配送地址若存在外送业务时使用。 【JSON字段】settlement_ticket_details.json - $ - deliveryAddress。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.deliveryFee IS '【说明】配送费金额(如果支持外送业务)。 【示例】NULL用于配送费金额如果支持外送业务。 【JSON字段】settlement_ticket_details.json - $ - deliveryFee。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.ledgerAmount IS '【说明】商品小计金额(通常 = 单价 × 数量,未考虑其他折扣)。 【示例】NULL用于商品小计金额通常 = 单价 × 数量,未考虑其他折扣))。 【JSON字段】settlement_ticket_details.json - $ - ledgerAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.memberDeductAmount IS '【说明】会员抵扣的某种数量或金额(例如积分抵现金额、次卡次数抵扣等),当前数据未启用。 【示例】NULL用于会员抵扣的某种数量或金额例如积分抵现金额、次卡次数抵扣等当前数据未启用。 【JSON字段】settlement_ticket_details.json - $ - memberDeductAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.memberOfferAmount IS '【说明】由“会员权益/折扣”产生的优惠金额总计(整单维度)。 【示例】NULL用于由“会员权益/折扣”产生的优惠金额总计(整单维度))。 【JSON字段】settlement_ticket_details.json - $ - memberOfferAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.onlineReturnAmount IS '【说明】本单通过线上支付渠道退回的金额(如微信/支付宝退款)。 【示例】NULL用于本单通过线上支付渠道退回的金额如微信/支付宝退款))。 【JSON字段】settlement_ticket_details.json - $ - onlineReturnAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.orderRemark IS '【说明】订单备注,由收银员录入,用于记录与本单相关的特殊说明。 【示例】NULL订单备注由收银员录入用于记录与本单相关的特殊说明。 【JSON字段】settlement_ticket_details.json - $ - orderRemark。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.orderSettleNumber IS '【说明】结算单编号(与 ID 独立的一套编号体系,如流水号)。 【示例】NULL用于结算单编号与 ID 独立的一套编号体系,如流水号))。 【JSON字段】settlement_ticket_details.json - $ - orderSettleNumber。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.payMemberBalance IS '【说明】使用会员余额支付的金额,用于区分与 balanceAmount 的不同维度(如“本次支付使用余额部分”与“余额本身变化”等),当前未实际使用。 【示例】NULL使用会员余额支付的金额用于区分与 balanceAmount 的不同维度(如“本次支付使用余额部分”与“余额本身变化”等),当前未实际使用)。 【JSON字段】settlement_ticket_details.json - $ - payMemberBalance。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.payTime IS '【说明】本单最终支付成功时间。 【示例】NULL用于本单最终支付成功时间。 【JSON字段】settlement_ticket_details.json - $ - payTime。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.paymentMethod IS '【说明】结算主支付方式编码(汇总视角)。 【示例】NULL用于结算主支付方式编码汇总视角。 【JSON字段】settlement_ticket_details.json - $ - paymentMethod。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.pointDiscountCost IS '【说明】积分抵扣对应的成本金额(成本侧)。 【示例】NULL用于积分抵扣对应的成本金额成本侧。 【JSON字段】settlement_ticket_details.json - $ - pointDiscountCost。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.pointDiscountPrice IS '【说明】积分抵扣对应的金额(售价侧)。 【示例】NULL用于积分抵扣对应的金额售价侧。 【JSON字段】settlement_ticket_details.json - $ - pointDiscountPrice。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.prepayMoney IS '【说明】预付金/定金在本单中使用的金额。 【示例】NULL用于预付金/定金在本单中使用的金额)。 【JSON字段】settlement_ticket_details.json - $ - prepayMoney。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.refundAmount IS '【说明】本单涉及的退款金额(汇总)。 【示例】NULL用于本单涉及的退款金额汇总。 【JSON字段】settlement_ticket_details.json - $ - refundAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.returnGoodsAmount IS '【说明】本单涉及的退货金额汇总。 【示例】NULL用于本单涉及的退货金额汇总。 【JSON字段】settlement_ticket_details.json - $ - returnGoodsAmount。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.rewardName IS '【说明】用于标识本单适用的激励方案名称,可能用于内部绩效或活动名称展示。 【示例】NULL用于标识本单适用的激励方案名称可能用于内部绩效或活动名称展示。 【JSON字段】settlement_ticket_details.json - $ - rewardName。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.settleType IS '【说明】结算类型字符串标识。 【示例】NULL用于结算类型字符串标识。 【JSON字段】settlement_ticket_details.json - $ - settleType。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.siteAddress IS '【说明】门店地址(详细地址)。 【示例】NULL用于门店地址详细地址。 【JSON字段】settlement_ticket_details.json - $ - siteAddress。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.siteBusinessTel IS '【说明】门店电话。 【示例】NULL用于门店电话。 【JSON字段】settlement_ticket_details.json - $ - siteBusinessTel。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.siteId IS '【说明】门店 ID。 【示例】NULL用于门店 ID。 【JSON字段】settlement_ticket_details.json - $ - siteId。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.siteName IS '【说明】门店名称,如“朗朗桌球”。 【示例】NULL用于门店名称如“朗朗桌球”。 【JSON字段】settlement_ticket_details.json - $ - siteName。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.tenantId IS '【说明】租户 / 商户 ID品牌维度。 【示例】NULL用于租户 / 商户 ID品牌维度。 【JSON字段】settlement_ticket_details.json - $ - tenantId。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.tenantName IS '【说明】租户名称,如“朗朗桌球”。 【示例】NULL用于租户名称如“朗朗桌球”。 【JSON字段】settlement_ticket_details.json - $ - tenantName。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.ticketCustomContent IS '【说明】自定义小票内容,如商家自定义宣传语、条款等。 【示例】NULL用于自定义小票内容如商家自定义宣传语、条款等。 【JSON字段】settlement_ticket_details.json - $ - ticketCustomContent。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.ticketRemark IS '【说明】小票备注内容,可用于打印在小票底部或顶部(例如活动说明、特别提示)。 【示例】NULL小票备注内容可用于打印在小票底部或顶部例如活动说明、特别提示。 【JSON字段】settlement_ticket_details.json - $ - ticketRemark。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.voucherMoney IS '【说明】代金券类金额字段(可能用于某类“代金券余额”或“券面值”记录)。 【示例】NULL代金券类金额字段可能用于某类“代金券余额”或“券面值”记录。 【JSON字段】settlement_ticket_details.json - $ - voucherMoney。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.memberProfile IS '【说明】不是会员卡主键,而是本次结账时的会员信息快照。 【示例】NULL用于不是会员卡主键而是本次结账时的会员信息快照。 【JSON字段】settlement_ticket_details.json - $ - memberProfile。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.orderItem IS '【说明】本次结算对应的“订单明细列表”,这部分是连接“台费流水 / 商品出库 / 券使用”等多个子领域的关键结构。 【示例】NULL用于本次结算对应的“订单明细列表”这部分是连接“台费流水 / 商品出库 / 券使用”等多个子领域的关键结构)。 【JSON字段】settlement_ticket_details.json - $ - orderItem。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.tenantMemberCardLogs IS '【说明】来自 JSON 导出的原始字段,用于保留业务取值。 【示例】NULL来自 JSON 导出的原始字段,用于保留业务取值)。 【JSON字段】settlement_ticket_details.json - $ - tenantMemberCardLogs。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.payload IS '【说明】完整原始 JSON 记录快照,用于回溯与二次解析。 【示例】{...}(完整原始 JSON 记录快照,用于回溯与二次解析)。 【JSON字段】settlement_ticket_details.json - $ - $。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.source_file IS '【说明】ETL 元数据:原始导出文件名,用于数据追溯。 【示例】settlement_ticket_details.jsonETL 元数据:原始导出文件名,用于数据追溯)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.source_endpoint IS '【说明】ETL 元数据:采集来源(接口/文件路径),用于数据追溯。 【示例】export/test-json-doc/settlement_ticket_details.jsonETL 元数据:采集来源(接口/文件路径),用于数据追溯)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
COMMENT ON COLUMN billiards_ods.settlement_ticket_details.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】settlement_ticket_details.json - ETL元数据 - 无。';
CREATE TABLE IF NOT EXISTS billiards_ods.store_goods_master (
id BIGINT,
tenant_id BIGINT,
@@ -2048,7 +1919,6 @@ COMMENT ON COLUMN billiards_ods.store_goods_sales_records.source_endpoint IS '
COMMENT ON COLUMN billiards_ods.store_goods_sales_records.fetched_at IS '【说明】ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理。 【示例】2025-11-10T00:00:00+08:00ETL 元数据:采集/入库时间戳,用于口径对齐与增量处理)。 【JSON字段】store_goods_sales_records.json - ETL元数据 - 无。';
-- AI_CHANGELOG:
-- - 日期: 2026-02-14
-- - Prompt: P20260214-070000 — ODS 清理与文档标注5 项任务)

View File

@@ -201,6 +201,20 @@ CREATE TABLE IF NOT EXISTS dim_table_ex (
table_cloth_use_time INTEGER,
table_cloth_use_cycle INTEGER,
table_status INTEGER,
create_time TIMESTAMPTZ,
light_status INTEGER,
tablestatusname TEXT,
sitename TEXT,
applet_qr_code_url TEXT,
audit_status INTEGER,
charge_free INTEGER,
delay_lights_time INTEGER,
is_rest_area INTEGER,
only_allow_groupon INTEGER,
order_delay_time INTEGER,
self_table INTEGER,
temporary_light_second INTEGER,
virtual_table INTEGER,
SCD2_start_time TIMESTAMPTZ DEFAULT now(),
SCD2_end_time TIMESTAMPTZ DEFAULT '9999-12-31',
SCD2_is_current INT DEFAULT 1,
@@ -311,6 +325,10 @@ CREATE TABLE IF NOT EXISTS dim_assistant_ex (
light_status INTEGER,
is_team_leader INTEGER,
serial_number BIGINT,
system_role_id BIGINT,
job_num TEXT,
cx_unit_price NUMERIC(18,2),
pd_unit_price NUMERIC(18,2),
SCD2_start_time TIMESTAMPTZ,
SCD2_end_time TIMESTAMPTZ,
SCD2_is_current INT,
@@ -748,7 +766,7 @@ COMMENT ON COLUMN billiards_dwd.dim_store_goods.goods_category_id IS '【说明
COMMENT ON COLUMN billiards_dwd.dim_store_goods.goods_second_category_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2793236829620037标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】store_goods_master - goods_second_category_id。 【JSON字段】store_goods_master.json - data.orderGoodsList - goods_second_category_id。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.category_level1_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】零食(名称字段,用于展示与辅助识别)。 【ODS来源】store_goods_master - oneCategoryName。 【JSON字段】store_goods_master.json - data.orderGoodsList - oneCategoryName。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.category_level2_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】面(名称字段,用于展示与辅助识别)。 【ODS来源】store_goods_master - twoCategoryName。 【JSON字段】store_goods_master.json - data.orderGoodsList - twoCategoryName。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.batch_stock_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】18数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - stock';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.batch_stock_qty IS '【说明】批次库存数量区别于当前库存stock。 【示例】18。 【ODS来源】store_goods_master - batch_stock_quantity。 【JSON字段】store_goods_master.json - data.orderGoodsList - batchStockQuantity';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.sale_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】104数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - sale_num。 【JSON字段】store_goods_master.json - data.orderGoodsList - sale_num。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.total_sales_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】104数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - total_sales。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_sales。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods.sale_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】12.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - sale_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - sale_price。';
@@ -792,6 +810,7 @@ CREATE TABLE IF NOT EXISTS dim_store_goods_ex (
option_required INTEGER,
remark TEXT,
sort_order INTEGER,
batch_stock_quantity INTEGER,
SCD2_start_time TIMESTAMPTZ,
SCD2_end_time TIMESTAMPTZ,
SCD2_is_current INT,
@@ -811,7 +830,7 @@ COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.stock_secondary_qty IS '【
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.safety_stock_qty IS '【说明】数量/时长字段,用于统计与计量。 【示例】0数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - safe_stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - safe_stock。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.cost_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - cost_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - cost_price。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.cost_price_type IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】1金额字段用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - cost_price_type。 【JSON字段】store_goods_master.json - data.orderGoodsList - cost_price_type。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.provisional_total_cost IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - total_purchase_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_purchase_cost。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.provisional_total_cost IS '【说明】暂估总成本区别于实际采购成本total_purchase_cost。 【示例】0.0。 【ODS来源】store_goods_master - provisional_total_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - provisionalTotalCost。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.total_purchase_cost IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - total_purchase_cost。 【JSON字段】store_goods_master.json - data.orderGoodsList - total_purchase_cost。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.min_discount_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】7.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_master - min_discount_price。 【JSON字段】store_goods_master.json - data.orderGoodsList - min_discount_price。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.is_discountable IS '【说明】数量/时长字段,用于统计与计量。 【示例】1数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_master - able_discount。 【JSON字段】store_goods_master.json - data.orderGoodsList - able_discount。';
@@ -826,6 +845,7 @@ COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.custom_label_type IS '【说
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.option_required IS '【说明】维度字段,用于补充维度属性。 【示例】1维度字段用于补充维度属性。 【ODS来源】store_goods_master - option_required。 【JSON字段】store_goods_master.json - data.orderGoodsList - option_required。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.remark IS '【说明】维度字段,用于补充维度属性。 【示例】NULL维度字段用于补充维度属性。 【ODS来源】store_goods_master - remark。 【JSON字段】store_goods_master.json - data.orderGoodsList - remark。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.sort_order IS '【说明】维度字段,用于补充维度属性。 【示例】100维度字段用于补充维度属性。 【ODS来源】store_goods_master - sort。 【JSON字段】store_goods_master.json - data.orderGoodsList - sort。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.batch_stock_quantity IS '【说明】批次库存数量,记录商品按批次管理的库存量。 【示例】0。 【ODS来源】store_goods_master - batch_stock。 【JSON字段】store_goods_master.json - data.orderGoodsList - batch_stock。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.scd2_start_time IS '【说明】SCD2 开始时间(版本生效起点),用于维度慢变追踪。 【示例】2025-11-10T00:00:00+08:00SCD2 开始时间(版本生效起点),用于维度慢变追踪)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.scd2_end_time IS '【说明】SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪。 【示例】9999-12-31T00:00:00+00:00SCD2 结束时间(默认 9999-12-31 表示当前版本),用于维度慢变追踪)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
COMMENT ON COLUMN billiards_dwd.dim_store_goods_ex.scd2_is_current IS '【说明】SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录。 【示例】1SCD2 当前版本标记1=当前0=历史),用于筛选最新维度记录)。 【ODS来源】store_goods_master - 无DWD慢变元数据。 【JSON字段】无 - DWD慢变元数据 - 无。';
@@ -1296,6 +1316,7 @@ CREATE TABLE IF NOT EXISTS dwd_store_goods_sale (
ledger_unit_price NUMERIC(18,2),
ledger_count INTEGER,
ledger_amount NUMERIC(18,2),
discount_money NUMERIC(18,2),
discount_price NUMERIC(18,2),
real_goods_money NUMERIC(18,2),
cost_money NUMERIC(18,2),
@@ -1324,7 +1345,8 @@ COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.ledger_group_name IS '【
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.ledger_unit_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - ledger_unit_price。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_unit_price。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.ledger_count IS '【说明】数量/时长字段,用于统计与计量。 【示例】1数量/时长字段,用于统计与计量)。 【ODS来源】store_goods_sales_records - ledger_count。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_count。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.ledger_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - ledger_amount。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_amount。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.discount_price IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - discount_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.discount_money IS '【说明】折扣金额,即原价被减免的金额部分。 【示例】0.0。 【ODS来源】store_goods_sales_records - discount_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_money。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.discount_price IS '【说明】折后单价(元/单位),即应用折扣后的商品单价。 【示例】5.00。 【ODS来源】store_goods_sales_records - discount_price。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - discount_price。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.real_goods_money IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - real_goods_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - real_goods_money。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.cost_money IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.01(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】store_goods_sales_records - cost_money。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - cost_money。';
COMMENT ON COLUMN billiards_dwd.dwd_store_goods_sale.ledger_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】1状态枚举字段用于标识业务状态。 【ODS来源】store_goods_sales_records - ledger_status。 【JSON字段】store_goods_sales_records.json - data.orderGoodsLedgers - ledger_status。';
@@ -1499,6 +1521,8 @@ CREATE TABLE IF NOT EXISTS dwd_assistant_service_log_ex (
grade_status INTEGER,
composite_grade_time TIMESTAMPTZ,
assistant_team_name TEXT,
operator_id BIGINT,
operator_name TEXT,
PRIMARY KEY (assistant_service_id)
);
@@ -1533,47 +1557,13 @@ COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.sum_grade IS '【
COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.get_grade_times IS '【说明】明细字段,用于记录事实取值。 【示例】0明细字段用于记录事实取值。 【ODS来源】assistant_service_records - get_grade_times。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - get_grade_times。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.grade_status IS '【说明】状态枚举字段,用于标识业务状态。 【示例】1状态枚举字段用于标识业务状态。 【ODS来源】assistant_service_records - grade_status。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - grade_status。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.composite_grade_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】0001-01-01 00:00:00时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】assistant_service_records - composite_grade_time。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - composite_grade_time。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.operator_id IS '【说明】操作人 ID记录执行该助教服务操作的系统用户。 【示例】2790687322443013。 【ODS来源】assistant_service_records - operator_id。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - operator_id。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_service_log_ex.operator_name IS '【说明】操作人姓名,用于展示与辅助识别。 【示例】收银员:郑丽珊。 【ODS来源】assistant_service_records - operator_name。 【JSON字段】assistant_service_records.json - data.orderAssistantDetails - operator_name。';
CREATE TABLE IF NOT EXISTS dwd_assistant_trash_event (
assistant_trash_event_id BIGINT,
site_id BIGINT,
table_id BIGINT,
table_area_id BIGINT,
assistant_no VARCHAR(32),
assistant_name VARCHAR(64),
charge_minutes_raw INTEGER,
abolish_amount NUMERIC(18,2),
trash_reason VARCHAR(255),
create_time TIMESTAMPTZ,
tenant_id BIGINT,
PRIMARY KEY (assistant_trash_event_id)
);
COMMENT ON TABLE billiards_dwd.dwd_assistant_trash_event IS 'DWD 明细事实表dwd_assistant_trash_event。ODS 来源表billiards_ods.assistant_cancellation_records对应 JSONassistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.assistant_trash_event_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957675849518789标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - id。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.site_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790685415443269标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - siteId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - siteId。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.table_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2793016660660357标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - tableId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableId。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.table_area_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2791963816579205标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - tableAreaId。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableAreaId。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.assistant_no IS '【说明】明细字段,用于记录事实取值。 【示例】泡芙(明细字段,用于记录事实取值)。 【ODS来源】assistant_cancellation_records - assistantName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.assistant_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】泡芙(名称字段,用于展示与辅助识别)。 【ODS来源】assistant_cancellation_records - assistantName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantName。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.charge_minutes_raw IS '【说明】明细字段,用于记录事实取值。 【示例】214明细字段用于记录事实取值。 【ODS来源】assistant_cancellation_records - pdChargeMinutes。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - pdChargeMinutes。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.abolish_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】5.83(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】assistant_cancellation_records - assistantAbolishAmount。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - assistantAbolishAmount。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.trash_reason IS '【说明】明细字段,用于记录事实取值。 【示例】NULL明细字段用于记录事实取值。 【ODS来源】assistant_cancellation_records - trashReason。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - trashReason。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event.create_time IS '【说明】时间/日期字段,用于记录业务时间与统计口径对齐。 【示例】2025-11-09 19:23:29时间/日期字段,用于记录业务时间与统计口径对齐)。 【ODS来源】assistant_cancellation_records - createTime。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - createTime。';
CREATE TABLE IF NOT EXISTS dwd_assistant_trash_event_ex (
assistant_trash_event_id BIGINT,
table_name VARCHAR(64),
table_area_name VARCHAR(64),
PRIMARY KEY (assistant_trash_event_id)
);
COMMENT ON TABLE billiards_dwd.dwd_assistant_trash_event_ex IS 'DWD 明细事实表扩展字段表dwd_assistant_trash_event_ex。ODS 来源表billiards_ods.assistant_cancellation_records对应 JSONassistant_cancellation_records.json分析assistant_cancellation_records-Analysis.md。装载/清洗逻辑参考etl_billiards/tasks/dwd_load_task.pyDwdLoadTask';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event_ex.assistant_trash_event_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2957675849518789标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】assistant_cancellation_records - id。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - id。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event_ex.table_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】C1名称字段用于展示与辅助识别。 【ODS来源】assistant_cancellation_records - tableName。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableName。';
COMMENT ON COLUMN billiards_dwd.dwd_assistant_trash_event_ex.table_area_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】C区名称字段用于展示与辅助识别。 【ODS来源】assistant_cancellation_records - tableArea。 【JSON字段】assistant_cancellation_records.json - data.abolitionAssistants - tableArea。';
-- [已删除] dwd_assistant_trash_event 和 dwd_assistant_trash_event_ex
-- 原因:助教废除链路已清理,废除判断改用 dwd_assistant_service_log_ex.is_trash
-- 参见迁移脚本2026-02-22__drop_assistant_abolish_tables.sql
CREATE TABLE IF NOT EXISTS dwd_member_balance_change (
@@ -1635,6 +1625,7 @@ CREATE TABLE IF NOT EXISTS dwd_member_balance_change_ex (
operator_id BIGINT,
operator_name VARCHAR(64),
principal_data TEXT,
relate_id BIGINT,
PRIMARY KEY (balance_change_id)
);
@@ -1645,6 +1636,7 @@ COMMENT ON COLUMN billiards_dwd.dwd_member_balance_change_ex.register_site_name
COMMENT ON COLUMN billiards_dwd.dwd_member_balance_change_ex.refund_amount IS '【说明】金额字段,用于计费/结算/核算等金额计算。 【示例】0.0(金额字段,用于计费/结算/核算等金额计算)。 【ODS来源】member_balance_changes - refund_amount。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - refund_amount。';
COMMENT ON COLUMN billiards_dwd.dwd_member_balance_change_ex.operator_id IS '【说明】标识类 ID 字段,用于关联/定位相关实体。 【示例】2790687322443013标识类 ID 字段,用于关联/定位相关实体)。 【ODS来源】member_balance_changes - operator_id。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - operator_id。';
COMMENT ON COLUMN billiards_dwd.dwd_member_balance_change_ex.operator_name IS '【说明】名称字段,用于展示与辅助识别。 【示例】收银员:郑丽珊(名称字段,用于展示与辅助识别)。 【ODS来源】member_balance_changes - operator_name。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - operator_name。';
COMMENT ON COLUMN billiards_dwd.dwd_member_balance_change_ex.relate_id IS '【说明】关联业务单据 ID指向触发本次余额变动的业务记录如充值单、订单、结算单等按 from_type 不同指向不同表。 【示例】2957881518788421。 【ODS来源】member_balance_changes - relate_id。 【JSON字段】member_balance_changes.json - data.tenantMemberCardLogs - relate_id。';
CREATE TABLE IF NOT EXISTS dwd_groupbuy_redemption (
@@ -2087,3 +2079,58 @@ COMMENT ON COLUMN billiards_dwd.dwd_refund_ex.channel_pay_no IS '【说明】明
-- - 直接原因: settle_list 列已从数据库删除DDL 需同步
-- - 变更摘要: 移除 dwd_settlement_head_ex 表定义中的 settle_list JSONB 列
-- - 风险与验证: 纯 DDL 文档同步;验证:对比 information_schema 确认一致
-- =============================================================================
-- 2026-02-20 新增表
-- =============================================================================
CREATE TABLE IF NOT EXISTS dwd_goods_stock_summary (
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC(18,4),
range_end_stock NUMERIC(18,4),
range_in NUMERIC(18,4),
range_out NUMERIC(18,4),
range_sale NUMERIC(18,4),
range_sale_money NUMERIC(18,2),
range_inventory NUMERIC(18,4),
current_stock NUMERIC(18,4),
site_id BIGINT,
tenant_id BIGINT,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_id, fetched_at)
);
COMMENT ON TABLE billiards_dwd.dwd_goods_stock_summary IS '库存汇总明细表事实表。来源ods.goods_stock_summary。按时间窗口增量加载。';
CREATE TABLE IF NOT EXISTS dwd_goods_stock_movement (
site_goods_stock_id BIGINT NOT NULL,
tenant_id BIGINT,
site_id BIGINT,
site_goods_id BIGINT,
goods_name TEXT,
goods_category_id BIGINT,
goods_second_category_id BIGINT,
unit TEXT,
price NUMERIC(18,4),
stock_type INTEGER,
change_num NUMERIC(18,4),
start_num NUMERIC(18,4),
end_num NUMERIC(18,4),
change_num_a NUMERIC(18,4),
start_num_a NUMERIC(18,4),
end_num_a NUMERIC(18,4),
remark TEXT,
operator_name TEXT,
create_time TIMESTAMPTZ,
fetched_at TIMESTAMPTZ,
PRIMARY KEY (site_goods_stock_id)
);
COMMENT ON TABLE billiards_dwd.dwd_goods_stock_movement IS '库存变动流水表事实表。来源ods.goods_stock_movements。按 create_time 增量加载。';

View File

@@ -202,7 +202,7 @@ CREATE INDEX idx_cfg_skill_type_course ON billiards_dws.cfg_skill_type (course_t
-- 6. dws_assistant_daily_detail - 助教日度业绩明细表
-- 说明:
-- - 以"助教+日期"为粒度,汇总每日业绩明细
-- - 数据来源: dwd_assistant_service_log + dwd_assistant_trash_event排除废除记录)
-- - 数据来源: dwd_assistant_service_log_ex通过 is_trash 字段判断废除记录)
-- - 更新频率: 每小时增量更新
-- - 时间分层: 通过 stat_date 筛选实现近2天/近1月/近3月/全量
-- -----------------------------------------------------------------------------
@@ -249,7 +249,7 @@ CREATE TABLE billiards_dws.dws_assistant_daily_detail (
COMMENT ON TABLE billiards_dws.dws_assistant_daily_detail IS '助教日度业绩明细:按助教+日期汇总服务次数、时长、金额,支持时间分层查询';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.assistant_level_code IS 'SCD2口径取stat_date当日生效的助教等级';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.trashed_seconds IS '被废除时长来自dwd_assistant_trash_event,影响有效业绩';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.trashed_seconds IS '被废除时长来自dwd_assistant_service_log_ex.is_trash,影响有效业绩';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.room_service_count IS '包厢/房间服务次数';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.room_seconds IS '包厢/房间计费时长(秒)';
COMMENT ON COLUMN billiards_dws.dws_assistant_daily_detail.room_hours IS '包厢/房间计费小时数';
@@ -398,7 +398,7 @@ CREATE INDEX idx_dws_assistant_customer_member ON billiards_dws.dws_assistant_cu
-- -----------------------------------------------------------------------------
-- 9. dws_assistant_salary_calc - 助教工资计算详情表
-- 说明:
-- - 以"助教+月份"为粒度,计算月度工资明细
-- - 以"助教+月份+档位"为粒度,计算月度工资明细
-- - 数据来源: dws_assistant_monthly_summary + cfg_* 配置表
-- - 计算公式来自DWS数据库处理需求.md:
-- * 基础课收入 = 基础课小时数 × (客户支付价格 - 专业课抽成)
@@ -457,7 +457,7 @@ CREATE TABLE billiards_dws.dws_assistant_salary_calc (
-- 元数据
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month)
CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month, assistant_level_code)
);
COMMENT ON TABLE billiards_dws.dws_assistant_salary_calc IS '助教工资计算详情按DWS数据库处理需求.md公式计算包含课时收入和各类奖金';
@@ -1673,3 +1673,112 @@ CREATE INDEX idx_dws_percentile_history ON billiards_dws.dws_index_percentile_hi
-- - 1张分位点历史表dws_index_percentile_history
-- - 1个召回优先级视图v_member_recall_priority
-- - 2个辅助函数get_time_window, get_comparison_window
-- =============================================================================
-- 2026-02-20 新增:库存汇总表(日/周/月)
-- =============================================================================
CREATE TABLE IF NOT EXISTS billiards_dws.dws_goods_stock_daily_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'daily',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE billiards_dws.dws_goods_stock_daily_summary
IS '库存日度汇总:按门店+日期+商品汇总库存变动';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_date
ON billiards_dws.dws_goods_stock_daily_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_goods
ON billiards_dws.dws_goods_stock_daily_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_daily_site
ON billiards_dws.dws_goods_stock_daily_summary (site_id, stat_date);
CREATE TABLE IF NOT EXISTS billiards_dws.dws_goods_stock_weekly_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'weekly',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE billiards_dws.dws_goods_stock_weekly_summary
IS '库存周度汇总:按门店+ISO周+商品汇总库存变动stat_date 为周一日期';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_date
ON billiards_dws.dws_goods_stock_weekly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_goods
ON billiards_dws.dws_goods_stock_weekly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_weekly_site
ON billiards_dws.dws_goods_stock_weekly_summary (site_id, stat_date);
CREATE TABLE IF NOT EXISTS billiards_dws.dws_goods_stock_monthly_summary (
site_id BIGINT NOT NULL,
tenant_id BIGINT,
stat_date DATE NOT NULL,
site_goods_id BIGINT NOT NULL,
goods_name TEXT,
goods_unit TEXT,
goods_category_id BIGINT,
goods_category_second_id BIGINT,
category_name TEXT,
range_start_stock NUMERIC,
range_end_stock NUMERIC,
range_in NUMERIC,
range_out NUMERIC,
range_sale NUMERIC,
range_sale_money NUMERIC(12,2),
range_inventory NUMERIC,
current_stock NUMERIC,
stat_period TEXT NOT NULL DEFAULT 'monthly',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (site_id, stat_date, site_goods_id)
);
COMMENT ON TABLE billiards_dws.dws_goods_stock_monthly_summary
IS '库存月度汇总:按门店+自然月+商品汇总库存变动stat_date 为月首日期';
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_date
ON billiards_dws.dws_goods_stock_monthly_summary (stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_goods
ON billiards_dws.dws_goods_stock_monthly_summary (site_goods_id, stat_date);
CREATE INDEX IF NOT EXISTS idx_dws_goods_stock_monthly_site
ON billiards_dws.dws_goods_stock_monthly_summary (site_id, stat_date);

View File

@@ -0,0 +1,81 @@
-- 迁移:创建 member_birthday_manual 表(助教手动补录会员生日)
-- 日期2026-02-22
-- 关联:需求 C2需求 5.1)— 助教手动补录会员生日
-- 目标库zqyy_app / test_zqyy_app
-- 影响:新建 member_birthday_manual 表 + 唯一约束 + 索引
-- 幂等CREATE TABLE IF NOT EXISTS / CREATE INDEX IF NOT EXISTS可重复执行
BEGIN;
-- ============================================================
-- 1. 创建 member_birthday_manual 表
-- ============================================================
CREATE TABLE IF NOT EXISTS member_birthday_manual (
id BIGSERIAL PRIMARY KEY,
member_id BIGINT NOT NULL,
birthday_value DATE NOT NULL,
recorded_by_assistant_id BIGINT,
recorded_by_name VARCHAR(50),
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
source VARCHAR(20) DEFAULT 'assistant',
site_id BIGINT NOT NULL,
CONSTRAINT uk_member_birthday_manual
UNIQUE (member_id, recorded_by_assistant_id)
);
COMMENT ON TABLE member_birthday_manual
IS '助教手动补录的会员生日信息';
-- ============================================================
-- 2. 创建索引
-- ============================================================
CREATE INDEX IF NOT EXISTS idx_mbd_member
ON member_birthday_manual (member_id);
CREATE INDEX IF NOT EXISTS idx_mbd_site_id
ON member_birthday_manual (site_id);
COMMIT;
-- ============================================================
-- 回滚(需手动执行,不在事务内)
-- ============================================================
-- BEGIN;
-- DROP TABLE IF EXISTS member_birthday_manual CASCADE;
-- COMMIT;
-- ============================================================
-- 验证 SQL
-- ============================================================
-- 1. 确认表存在
-- SELECT table_name
-- FROM information_schema.tables
-- WHERE table_schema = 'public'
-- AND table_name = 'member_birthday_manual';
-- 预期1 行
-- 2. 确认唯一约束 uk_member_birthday_manual 存在
-- SELECT conname, contype
-- FROM pg_constraint
-- WHERE conrelid = 'member_birthday_manual'::regclass
-- AND conname = 'uk_member_birthday_manual';
-- 预期1 行contype = 'u'
-- 3. 确认索引 idx_mbd_member 存在
-- SELECT indexname
-- FROM pg_indexes
-- WHERE tablename = 'member_birthday_manual'
-- AND indexname = 'idx_mbd_member';
-- 预期1 行
-- 4. 确认表注释已设置
-- SELECT obj_description('member_birthday_manual'::regclass, 'pg_class');
-- 预期:'助教手动补录的会员生日信息'
-- 5. 确认列结构完整8 列)
-- SELECT column_name, data_type, is_nullable
-- FROM information_schema.columns
-- WHERE table_schema = 'public'
-- AND table_name = 'member_birthday_manual'
-- ORDER BY ordinal_position;
-- 预期id, member_id, birthday_value, recorded_by_assistant_id,
-- recorded_by_name, recorded_at, source, site_id

View File

@@ -100,3 +100,28 @@ CREATE TABLE IF NOT EXISTS approvals (
CREATE INDEX IF NOT EXISTS idx_approvals_site_id ON approvals (site_id);
CREATE INDEX IF NOT EXISTS idx_approvals_task_id ON approvals (task_id);
-- ---------------------------------------------------------------------------
-- member_birthday_manual 表:助教手动补录的会员生日信息
-- 关联迁移2026-02-22__C2_member_birthday_manual.sql
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS member_birthday_manual (
id BIGSERIAL PRIMARY KEY,
member_id BIGINT NOT NULL,
birthday_value DATE NOT NULL,
recorded_by_assistant_id BIGINT,
recorded_by_name VARCHAR(50),
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
source VARCHAR(20) DEFAULT 'assistant',
site_id BIGINT NOT NULL,
CONSTRAINT uk_member_birthday_manual
UNIQUE (member_id, recorded_by_assistant_id)
);
COMMENT ON TABLE member_birthday_manual
IS '助教手动补录的会员生日信息';
CREATE INDEX IF NOT EXISTS idx_mbd_member
ON member_birthday_manual (member_id);
CREATE INDEX IF NOT EXISTS idx_mbd_site_id
ON member_birthday_manual (site_id);

View File

@@ -1,80 +1,29 @@
# database/ — 数据库
# db/etl_feiqiu/ — ETL 数据库资产
## 文件说明
## 六层 Schema
| Schema | 用途 | DDL 基线 |
|--------|------|---------|
| meta | ETL 调度元数据(任务注册、游标、运行记录) | `docs/database/ddl/etl_feiqiu__meta.sql` |
| ods | 原始数据层API payload 落地) | `docs/database/ddl/etl_feiqiu__ods.sql` |
| dwd | 明细数据层(维度 SCD2 + 事实增量) | `docs/database/ddl/etl_feiqiu__dwd.sql` |
| core | 跨门店标准化维度/事实 | `docs/database/ddl/etl_feiqiu__core.sql` |
| dws | 汇总数据层(业绩、财务、会员、工资、指数) | `docs/database/ddl/etl_feiqiu__dws.sql` |
| app | RLS 视图层(仅视图,无表) | `docs/database/ddl/etl_feiqiu__app.sql` |
## 种子数据
| 文件 | 用途 |
|------|------|
| `connection.py` | 数据库连接管理(带超时的 psycopg2 封装) |
| `operations.py` | 批量操作upsert、execute、query |
| `base.py` | 数据库操作基础类 |
## DDL Schema 文件
> CHANGE 2026-02-15 | 对齐新库 etl_feiqiu 六层架构,旧 schema 名已弃用
| 文件 | Schema | 说明 |
|------|-------------|------|
| `schema_ODS_doc.sql` | `ods` | ODS 层表结构(含字段注释) |
| `schema_dwd_doc.sql` | `dwd` | DWD 层表结构(维度 + 事实,含 SCD2 列) |
| `schema_dws.sql` | `dws` | DWS 层表结构(汇总表 + 配置表) |
| `schema_etl_admin.sql` | `meta` | ETL 元数据(任务注册、游标、运行记录) |
| `schema_verify_perf_indexes.sql` | 各 Schema | 校验性能索引(仅索引 + ANALYZE |
## 种子脚本
| 文件 | 用途 |
|------|------|
| `seed_ods_tasks.sql` | 注册 ODS 任务到 `meta.etl_task` |
| `seed_scheduler_tasks.sql` | 初始化调度任务配置 |
| `seed_dws_config.sql` | DWS 配置数据(绩效档位、等级定价、技能映射等) |
| `seed_index_parameters.sql` | 指数算法参数WBI/NCI/RS/OS/MS/ML |
## 迁移脚本
位于 `migrations/` 子目录,纯 SQL按日期前缀命名
```
migrations/
├── 20260208_relation_index_manual_ml.sql
├── 20260214_drop_ods_settlelist.sql
├── 20260214_drop_dwd_settle_list.sql
└── 20260214_drop_ods_option_name_able_site_transfer.sql
```
新增迁移时,文件名格式:`YYYYMMDD_描述.sql`
| `seeds/seed_ods_tasks.sql` | 注册 ODS 抓取任务到 `meta.etl_task` |
| `seeds/seed_scheduler_tasks.sql` | 初始化调度任务配置 |
| `seeds/seed_dws_config.sql` | DWS 配置(绩效档位、等级定价、技能映射等) |
| `seeds/seed_index_parameters.sql` | 指数算法参数WBI/NCI/RS/OS/MS/ML |
## Schema 约定
- 所有 DDL 使用 `CREATE TABLE IF NOT EXISTS`,支持幂等执行
- 表名小写蛇形,带 Schema 前缀(如 `dwd.dim_member`
- 维度表包含 SCD2 列:`scd2_start_time``scd2_end_time``scd2_is_current``scd2_version`
- ODS 表包含元数据列:`content_hash``payload``fetched_at``source_file`
- 金额字段统一 `NUMERIC(12,2)`ID 字段统一 `BIGINT`
- 不使用 ORM所有 SQL 通过 `psycopg2` 直接执行
<!--
AI_CHANGELOG:
- 日期: 2026-02-14
- Prompt: P20260214-030000 — 上下文传递续接,完成 settlelist 删除后的变更影响审查
- 直接原因: Change Impact Review 要求将新增迁移脚本同步到 database/README.md
- 变更摘要: 迁移脚本列表新增 20260214_drop_ods_settlelist.sql 条目
- 风险与验证: 纯文档变更,无运行时影响;验证方式:`ls database/migrations/` 确认文件存在
-->
<!--
AI_CHANGELOG:
- 日期: 2026-02-14
- Prompt: P20260214-040000 — "dwd_settlement_head_ex.settle_list 也没有必要保留了"
- 直接原因: 新增迁移脚本需同步到 README 迁移列表
- 变更摘要: 迁移脚本列表新增 20260214_drop_dwd_settle_list.sql
- 风险与验证: 纯文档变更验证ls database/migrations/ 确认文件存在
-->
<!--
AI_CHANGELOG:
- 日期: 2026-02-14
- Prompt: P20260214-070000 — ODS 清理(删除 option_name/able_site_transfer变更影响审查
- 直接原因: Change Impact Review 要求将新增迁移脚本同步到 database/README.md
- 变更摘要: 迁移脚本列表新增 20260214_drop_ods_option_name_able_site_transfer.sql
- 风险与验证: 纯文档变更验证ls database/migrations/ 确认文件存在
-->
- 表名小写蛇形,带 schema 前缀(如 `dwd.dim_member`
- 维度表含 SCD2 列:`scd2_start_time``scd2_end_time``scd2_is_current``scd2_version`
- ODS 表含元数据列:`content_hash``payload``fetched_at``source_file`
- 金额字段 `NUMERIC(12,2)`ID 字段 `BIGINT`
- 不使用 ORMSQL 通过 `psycopg2` 直接执行

View File

@@ -0,0 +1,139 @@
-- =============================================================================
-- 迁移脚本:创建员工档案 ODS + DWD 表
-- 日期2026-02-22
-- 说明:从 SearchSystemStaffInfo API 抓取员工数据ODS 落地后清洗至 DWD 维度表
-- 需求US-1, US-2, US-3
-- =============================================================================
-- ---------------------------------------------------------------------------
-- 1. ODS 层ods.staff_info_master
-- ---------------------------------------------------------------------------
CREATE TABLE ods.staff_info_master (
id BIGINT NOT NULL,
tenant_id BIGINT,
site_id BIGINT,
tenant_org_id BIGINT,
system_user_id BIGINT,
staff_name TEXT,
alias_name TEXT,
mobile TEXT,
avatar TEXT,
gender INTEGER,
job TEXT,
job_num TEXT,
staff_identity INTEGER,
status INTEGER,
account_status INTEGER,
system_role_id INTEGER,
rank_id INTEGER,
rank_name TEXT,
new_rank_id INTEGER,
new_staff_identity INTEGER,
leave_status INTEGER,
entry_time TIMESTAMP WITHOUT TIME ZONE,
resign_time TIMESTAMP WITHOUT TIME ZONE,
create_time TIMESTAMP WITHOUT TIME ZONE,
is_delete INTEGER,
is_reserve INTEGER,
shop_name TEXT,
site_label TEXT,
cashier_point_id BIGINT,
cashier_point_name TEXT,
group_id BIGINT,
group_name TEXT,
staff_profile_id BIGINT,
auth_code TEXT,
auth_code_create TIMESTAMP WITHOUT TIME ZONE,
ding_talk_synced INTEGER,
salary_grant_enabled INTEGER,
entry_type INTEGER,
entry_sign_status INTEGER,
resign_sign_status INTEGER,
criticism_status INTEGER,
user_roles JSONB,
-- ETL 元数据
content_hash TEXT NOT NULL,
source_file TEXT,
fetched_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
payload JSONB NOT NULL
);
COMMENT ON TABLE ods.staff_info_master IS '员工档案主数据来源SearchSystemStaffInfo API';
-- ---------------------------------------------------------------------------
-- 2. DWD 层dwd.dim_staff主表核心业务字段SCD2
-- ---------------------------------------------------------------------------
CREATE TABLE dwd.dim_staff (
staff_id BIGINT NOT NULL,
staff_name TEXT,
alias_name TEXT,
mobile TEXT,
gender INTEGER,
job TEXT,
tenant_id BIGINT,
site_id BIGINT,
system_role_id INTEGER,
staff_identity INTEGER,
status INTEGER,
leave_status INTEGER,
entry_time TIMESTAMP WITH TIME ZONE,
resign_time TIMESTAMP WITH TIME ZONE,
is_delete INTEGER,
-- SCD2
scd2_start_time TIMESTAMP WITH TIME ZONE NOT NULL,
scd2_end_time TIMESTAMP WITH TIME ZONE,
scd2_is_current INTEGER,
scd2_version INTEGER,
PRIMARY KEY (staff_id, scd2_start_time)
);
COMMENT ON TABLE dwd.dim_staff IS '员工档案维度主表SCD2';
-- ---------------------------------------------------------------------------
-- 3. DWD 层dwd.dim_staff_ex扩展表次要/低频变更字段SCD2
-- ---------------------------------------------------------------------------
CREATE TABLE dwd.dim_staff_ex (
staff_id BIGINT NOT NULL,
avatar TEXT,
job_num TEXT,
account_status INTEGER,
rank_id INTEGER,
rank_name TEXT,
new_rank_id INTEGER,
new_staff_identity INTEGER,
is_reserve INTEGER,
shop_name TEXT,
site_label TEXT,
tenant_org_id BIGINT,
system_user_id BIGINT,
cashier_point_id BIGINT,
cashier_point_name TEXT,
group_id BIGINT,
group_name TEXT,
staff_profile_id BIGINT,
auth_code TEXT,
auth_code_create TIMESTAMP WITH TIME ZONE,
ding_talk_synced INTEGER,
salary_grant_enabled INTEGER,
entry_type INTEGER,
entry_sign_status INTEGER,
resign_sign_status INTEGER,
criticism_status INTEGER,
create_time TIMESTAMP WITH TIME ZONE,
user_roles JSONB,
-- SCD2
scd2_start_time TIMESTAMP WITH TIME ZONE NOT NULL,
scd2_end_time TIMESTAMP WITH TIME ZONE,
scd2_is_current INTEGER,
scd2_version INTEGER,
PRIMARY KEY (staff_id, scd2_start_time)
);
COMMENT ON TABLE dwd.dim_staff_ex IS '员工档案维度扩展表SCD2';
-- =============================================================================
-- 回滚脚本(如需撤销)
-- DROP TABLE IF EXISTS dwd.dim_staff_ex;
-- DROP TABLE IF EXISTS dwd.dim_staff;
-- DROP TABLE IF EXISTS ods.staff_info_master;
-- =============================================================================

View File

@@ -0,0 +1,70 @@
-- =============================================================================
-- 迁移脚本:创建 dws.dws_member_spending_power_index 表
-- 日期2026-02-23
-- 说明SPI消费力指数结果表存储会员级消费力评分及中间特征
-- 需求1.1, 1.2, 1.3, 1.4, 1.5
-- =============================================================================
-- 序列BIGSERIAL 自动创建,此处显式声明以保持与项目风格一致)
CREATE SEQUENCE IF NOT EXISTS dws.dws_member_spending_power_index_spi_id_seq AS bigint;
-- 主表
CREATE TABLE dws.dws_member_spending_power_index (
spi_id BIGINT DEFAULT nextval('dws.dws_member_spending_power_index_spi_id_seq'::regclass) NOT NULL,
site_id INTEGER NOT NULL,
member_id BIGINT NOT NULL,
-- 基础特征
spend_30 NUMERIC(14,2) DEFAULT 0, -- 近30天消费总额
spend_90 NUMERIC(14,2) DEFAULT 0, -- 近90天消费总额
recharge_90 NUMERIC(14,2) DEFAULT 0, -- 近90天充值总额
orders_30 INTEGER DEFAULT 0, -- 近30天消费笔数
orders_90 INTEGER DEFAULT 0, -- 近90天消费笔数
visit_days_30 INTEGER DEFAULT 0, -- 近30天消费日数按天去重
visit_days_90 INTEGER DEFAULT 0, -- 近90天消费日数按天去重
avg_ticket_90 NUMERIC(14,2) DEFAULT 0, -- 90天客单价
active_weeks_90 INTEGER DEFAULT 0, -- 近90天有消费的自然周数最多13
daily_spend_ewma_90 NUMERIC(14,2) DEFAULT 0, -- 日消费 EWMA
-- 子分Raw算法直接计算的未归一化分数
score_level_raw NUMERIC(10,4) DEFAULT 0, -- Level 子分原始分
score_speed_raw NUMERIC(10,4) DEFAULT 0, -- Speed 子分原始分
score_stability_raw NUMERIC(10,4) DEFAULT 0, -- Stability 子分原始分
-- 子分Display归一化到 0-10 的展示分)
score_level_display NUMERIC(5,2) DEFAULT 0,
score_speed_display NUMERIC(5,2) DEFAULT 0,
score_stability_display NUMERIC(5,2) DEFAULT 0,
-- 总分
raw_score NUMERIC(10,4) DEFAULT 0, -- SPI 原始分(加权合成)
display_score NUMERIC(5,2) DEFAULT 0, -- SPI 展示分0-10
-- 元数据
calc_time TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- 主键
CONSTRAINT dws_member_spending_power_index_pkey PRIMARY KEY (spi_id)
);
-- 唯一约束(业务主键:一个门店一个会员只有一条记录)
CREATE UNIQUE INDEX idx_spi_site_member
ON dws.dws_member_spending_power_index (site_id, member_id);
-- 查询索引(按门店查询展示分排名)
CREATE INDEX idx_spi_display_score
ON dws.dws_member_spending_power_index (site_id, display_score DESC);
-- 序列归属
ALTER SEQUENCE dws.dws_member_spending_power_index_spi_id_seq
OWNED BY dws.dws_member_spending_power_index.spi_id;
-- =============================================================================
-- 回滚脚本(如需撤销)
-- DROP INDEX IF EXISTS dws.idx_spi_display_score;
-- DROP INDEX IF EXISTS dws.idx_spi_site_member;
-- DROP TABLE IF EXISTS dws.dws_member_spending_power_index;
-- DROP SEQUENCE IF EXISTS dws.dws_member_spending_power_index_spi_id_seq;
-- =============================================================================

View File

@@ -1,116 +1,96 @@
-- =============================================================================
-- DWS 配置表初始数据
-- 版本: v3.0
-- 版本: v4.0
-- 创建日期: 2026-02-01
-- 更新日期: 2026-02-21
-- AI_CHANGELOG [2026-02-21] 取消全文注释,数据已写入 test_etl_feiqiu
-- 新增 2025-01-01~2026-02-28 统一提成档位基础课18元/小时打赏课40%
-- 新增 GUARANTEE 保底奖金规则按等级初级12000/中级16000/高级18000/星级23000
-- 历史分档口径截止日期调整为 2024-12-31
-- 描述: 初始化配置表数据,包含绩效档位、等级定价、奖金规则、区域分类、技能映射
-- =============================================================================
-- NOTE: 当前数据库 cfg_* 配置表为空(以数据库现状为准)
-- 下方默认配置仅作参考,已整体注释
/*
-- =============================================================================
-- 1. cfg_performance_tier - 绩效档位配置(含历史口径)
-- 数据来源DWS 数据库处理需求.md
-- 旧方案历史口径至2026-02-28:
-- 0档 淘汰压力 H <100 28 50% 3
-- 1档 及格档(重点激励) 100≤ H <130 18 40% 4
-- 2档 良好档(重点激励) 130≤ H <160 15 38% 4
-- 3档 优秀档 160≤ H <190 13 35% 5
-- 4档 卓越加速档(高端人才倾斜) 190≤ H <220 10 33% 6
-- 5档 冠军加速档(高端人才倾斜) H ≥220 8 30% 休假自由
-- 新方案2026-03-01起:
-- 0档 淘汰压力 H <120 28 50% 3
-- 1档 及格档 120≤ H <150 18 40% 4
-- 2档 良好档 150≤ H <180 13 35% 5
-- 3档 优秀档 180≤ H <210 10 30% 6
-- 4档 销冠竞争 H ≥210 8 25% 休假自由
-- 三段时间线:
-- 2000-01-01 ~ 2024-12-31: 旧方案6档阶梯抽成
-- 2025-01-01 ~ 2026-02-28: 统一提成不分档基础课18元/小时,打赏课40%
-- 2026-03-01 ~ 9999-12-31: 新方案5档阶梯抽成
-- =============================================================================
TRUNCATE TABLE dws.cfg_performance_tier RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_performance_tier (
tier_code, tier_name, tier_level,
min_hours, max_hours,
tier_code, tier_name, tier_level,
min_hours, max_hours,
base_deduction, bonus_deduction_ratio, vacation_days, vacation_unlimited,
is_new_hire_tier, effective_from, effective_to, description
) VALUES
-- 旧方案至2026-02-28
-- 0档 淘汰压力: H<100, 专业课抽成28元/小时, 打赏课抽成50%, 休假3天
('T0', '0档-淘汰压力', 0,
0, 100,
-- 旧方案至2024-12-31
('T0', '0档-淘汰压力', 0,
0, 100,
28.00, 0.50, 3, FALSE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案H<100专业课抽成28元/小时打赏课抽成50%休假3天'),
-- 1档 及格档: 100≤H<130, 专业课抽成18元/小时, 打赏课抽成40%, 休假4天
('T1', '1档-及格档', 1,
100, 130,
('T1', '1档-及格档', 1,
100, 130,
18.00, 0.40, 4, FALSE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案100≤H<130专业课抽成18元/小时打赏课抽成40%休假4天'),
-- 2档 良好档: 130≤H<160, 专业课抽成15元/小时, 打赏课抽成38%, 休假4天
('T2', '2档-良好档', 2,
130, 160,
('T2', '2档-良好档', 2,
130, 160,
15.00, 0.38, 4, FALSE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案130≤H<160专业课抽成15元/小时打赏课抽成38%休假4天'),
-- 3档 优秀档: 160≤H<190, 专业课抽成13元/小时, 打赏课抽成35%, 休假5天
('T3', '3档-优秀档', 3,
160, 190,
('T3', '3档-优秀档', 3,
160, 190,
13.00, 0.35, 5, FALSE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案160≤H<190专业课抽成13元/小时打赏课抽成35%休假5天'),
-- 4档 卓越加速档: 190≤H<220, 专业课抽成10元/小时, 打赏课抽成33%, 休假6天
('T4', '4档-卓越加速档', 4,
190, 220,
('T4', '4档-卓越加速档', 4,
190, 220,
10.00, 0.33, 6, FALSE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案190≤H<220专业课抽成10元/小时打赏课抽成33%休假6天'),
-- 5档 冠军加速档: H≥220, 专业课抽成8元/小时, 打赏课抽成30%, 休假自由
('T5', '5档-冠军加速档', 5,
220, NULL,
('T5', '5档-冠军加速档', 5,
220, NULL,
8.00, 0.30, 0, TRUE,
FALSE, '2000-01-01', '2026-02-28',
FALSE, '2000-01-01', '2024-12-31',
'旧方案H≥220专业课抽成8元/小时打赏课抽成30%,休假自由'),
-- 2025-01-01 ~ 2026-02-28: 统一提成(不分档,所有助教统一规则)
-- CHANGE 2026-02-21 | 新增统一提成档位基础课球房提成18元/小时打赏课球房提成40%
('T0', '统一档', 0,
0, NULL,
18.00, 0.40, 0, FALSE,
FALSE, '2025-01-01', '2026-02-28',
'2025-01-01~2026-02-28统一规则基础课球房提成18元/小时打赏课球房提成40%,不分档位'),
-- 新方案2026-03-01起
-- 0档 淘汰压力: H<120, 专业课抽成28元/小时, 打赏课抽成50%, 休假3天
('T0', '0档-淘汰压力', 0,
0, 120,
('T0', '0档-淘汰压力', 0,
0, 120,
28.00, 0.50, 3, FALSE,
FALSE, '2026-03-01', '9999-12-31',
FALSE, '2026-03-01', '9999-12-31',
'新方案H<120专业课抽成28元/小时打赏课抽成50%休假3天'),
-- 1档 及格档: 120≤H<150, 专业课抽成18元/小时, 打赏课抽成40%, 休假4天
('T1', '1档-及格档', 1,
120, 150,
('T1', '1档-及格档', 1,
120, 150,
18.00, 0.40, 4, FALSE,
FALSE, '2026-03-01', '9999-12-31',
FALSE, '2026-03-01', '9999-12-31',
'新方案120≤H<150专业课抽成18元/小时打赏课抽成40%休假4天'),
-- 2档 良好档: 150≤H<180, 专业课抽成13元/小时, 打赏课抽成35%, 休假5天
('T2', '2档-良好档', 2,
150, 180,
('T2', '2档-良好档', 2,
150, 180,
13.00, 0.35, 5, FALSE,
FALSE, '2026-03-01', '9999-12-31',
FALSE, '2026-03-01', '9999-12-31',
'新方案150≤H<180专业课抽成13元/小时打赏课抽成35%休假5天'),
-- 3档 优秀档: 180≤H<210, 专业课抽成10元/小时, 打赏课抽成30%, 休假6天
('T3', '3档-优秀档', 3,
180, 210,
('T3', '3档-优秀档', 3,
180, 210,
10.00, 0.30, 6, FALSE,
FALSE, '2026-03-01', '9999-12-31',
FALSE, '2026-03-01', '9999-12-31',
'新方案180≤H<210专业课抽成10元/小时打赏课抽成30%休假6天'),
-- 4档 销冠竞争: H≥210, 专业课抽成8元/小时, 打赏课抽成25%, 休假自由
('T4', '4档-销冠竞争', 4,
210, NULL,
('T4', '4档-销冠竞争', 4,
210, NULL,
8.00, 0.25, 0, TRUE,
FALSE, '2026-03-01', '9999-12-31',
FALSE, '2026-03-01', '9999-12-31',
'新方案H≥210专业课抽成8元/小时打赏课抽成25%,休假自由');
@@ -121,51 +101,46 @@ INSERT INTO dws.cfg_performance_tier (
-- - 8=助教管理, 10=初级, 20=中级, 30=高级, 40=星级
-- - 价格为客户支付价格(对外价格),助教收入=客户支付-档位抽成
-- - 包厢课基础课统一138元/小时(不随等级变化)
-- - 数据来源DWS 数据库处理需求.md
-- =============================================================================
TRUNCATE TABLE dws.cfg_assistant_level_price RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_assistant_level_price (
level_code, level_name,
level_code, level_name,
base_course_price, bonus_course_price,
effective_from, effective_to, description
) VALUES
-- 初级助教基础课对客户收费98元/小时
(10, '初级',
(10, '初级',
98.00, 190.00,
'2000-01-01', '9999-12-31',
'2000-01-01', '9999-12-31',
'初级助教基础课98元/时附加课190元/时(客户支付价格)'),
-- 中级助教基础课对客户收费108元/小时
(20, '中级',
(20, '中级',
108.00, 190.00,
'2000-01-01', '9999-12-31',
'2000-01-01', '9999-12-31',
'中级助教基础课108元/时附加课190元/时(客户支付价格)'),
-- 高级助教基础课对客户收费118元/小时
(30, '高级',
(30, '高级',
118.00, 190.00,
'2000-01-01', '9999-12-31',
'2000-01-01', '9999-12-31',
'高级助教基础课118元/时附加课190元/时(客户支付价格)'),
-- 星级助教基础课对客户收费138元/小时
(40, '星级',
(40, '星级',
138.00, 190.00,
'2000-01-01', '9999-12-31',
'2000-01-01', '9999-12-31',
'星级助教基础课138元/时附加课190元/时(客户支付价格)'),
-- 助教管理level_code=8通常不参与客户服务计费此处设置默认值
(8, '助教管理',
(8, '助教管理',
98.00, 190.00,
'2000-01-01', '9999-12-31',
'2000-01-01', '9999-12-31',
'助教管理:不参与客户服务计费,默认按初级价格');
-- =============================================================================
-- 3. cfg_bonus_rules - 奖金规则配置
-- 说明:
-- - SPRINT: 冲刺奖金历史口径至2026-02-28
-- - SPRINT: 冲刺奖金历史口径至2024-12-31
-- - GUARANTEE: 保底月薪线2025-01-01~2026-02-28按等级区分
-- * 保底规则:总课时达标 + 打赏课≥10小时 → 触发保底月薪线
-- * 保底含义:实发 = MAX(课时收入+奖金, 保底金额),非额外奖金
-- * rule_code 中 LV10/LV20/LV30/LV40 对应 level_code
-- - TOP_RANK: Top3排名奖金2026-03-01起
-- CHANGE 2026-02-21 | 新增 GUARANTEE 保底奖金规则
-- =============================================================================
TRUNCATE TABLE dws.cfg_bonus_rules RESTART IDENTITY CASCADE;
@@ -175,39 +150,56 @@ INSERT INTO dws.cfg_bonus_rules (
is_cumulative, priority,
effective_from, effective_to, description
) VALUES
-- 冲刺奖金: H>=190 得300元(历史口径)
-- 冲刺奖金(历史口径至2024-12-31
('SPRINT', 'SPRINT_190', '冲刺奖金190',
190.00, NULL, 300.00,
FALSE, 1,
'2000-01-01', '2026-02-28',
'2000-01-01', '2024-12-31',
'历史口径业绩≥190小时获得300元冲刺奖金不累计'),
-- 冲刺奖金: H>=220 得800元历史口径优先级更高覆盖190档
('SPRINT', 'SPRINT_220', '冲刺奖金220',
220.00, NULL, 800.00,
FALSE, 2,
'2000-01-01', '2026-02-28',
'2000-01-01', '2024-12-31',
'历史口径业绩≥220小时获得800元冲刺奖金覆盖190档'),
-- Top1排名奖金: 1000元2026-03-01起
-- 保底奖金2025-01-01 ~ 2026-02-28
-- 按助教等级区分需同时满足总课时和打赏课最低时数≥10小时
('GUARANTEE', 'GUAR_LV10', '初级保底奖金',
130.00, NULL, 12000.00,
FALSE, 10,
'2025-01-01', '2026-02-28',
'初级保底完成130小时课程含≥10小时打赏课保底月薪线12000元实发=MAX(课时收入+奖金, 12000)'),
('GUARANTEE', 'GUAR_LV20', '中级保底奖金',
150.00, NULL, 16000.00,
FALSE, 20,
'2025-01-01', '2026-02-28',
'中级保底完成150小时课程含≥10小时打赏课保底月薪线16000元实发=MAX(课时收入+奖金, 16000)'),
('GUARANTEE', 'GUAR_LV30', '高级保底奖金',
160.00, NULL, 18000.00,
FALSE, 30,
'2025-01-01', '2026-02-28',
'高级保底完成160小时课程含≥10小时打赏课保底月薪线18000元实发=MAX(课时收入+奖金, 18000)'),
('GUARANTEE', 'GUAR_LV40', '星级保底奖金',
170.00, NULL, 23000.00,
FALSE, 40,
'2025-01-01', '2026-02-28',
'星级保底完成170小时课程含≥10小时打赏课保底月薪线23000元实发=MAX(课时收入+奖金, 23000)'),
-- Top排名奖金2026-03-01起
('TOP_RANK', 'TOP_1', 'Top1排名奖金',
NULL, 1, 1000.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'2026-03-01', '9999-12-31',
'月度排名第一获得1000元并列都算'),
-- Top2排名奖金: 600元2026-03-01起
('TOP_RANK', 'TOP_2', 'Top2排名奖金',
NULL, 2, 600.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'2026-03-01', '9999-12-31',
'月度排名第二获得600元并列都算'),
-- Top3排名奖金: 400元2026-03-01起
('TOP_RANK', 'TOP_3', 'Top3排名奖金',
NULL, 3, 400.00,
FALSE, 0,
'2026-03-01', '9999-12-31',
'2026-03-01', '9999-12-31',
'月度排名第三获得400元并列都算');
@@ -217,14 +209,6 @@ INSERT INTO dws.cfg_bonus_rules (
-- - 将 dim_table.site_table_area_name 映射到财务报表区域分类
-- - 映射规则: 精确匹配 > 模糊匹配 > 默认兜底
-- - 数据来源: BD_manual_dim_table.md 中的 site_table_area_name 实际分布
-- 分类设计:
-- - BILLIARD: 台球散台A区/B区/C区/TV台
-- - BILLIARD_VIP: 台球VIP包厢
-- - SNOOKER: 斯诺克区
-- - MAHJONG: 麻将区
-- - KTV: K歌/KTV
-- - SPECIAL: 特殊(补时长等)
-- - OTHER: 其他
-- =============================================================================
TRUNCATE TABLE dws.cfg_area_category RESTART IDENTITY CASCADE;
@@ -232,63 +216,35 @@ INSERT INTO dws.cfg_area_category (
source_area_name, category_code, category_name,
match_type, match_priority, is_active, description
) VALUES
-- ============ 台球散台(精确匹配)============
('A区', 'BILLIARD', '台球散台',
'EXACT', 10, TRUE, '台球散台:A18台)- 中八/追分'),
('B区', 'BILLIARD', '台球散台',
'EXACT', 10, TRUE, '台球散台:B区15台)- 中八/追分'),
('C区', 'BILLIARD', '台球散台',
'EXACT', 10, TRUE, '台球散台C区6台- 中八/追分'),
('TV台', 'BILLIARD', '台球散台',
'EXACT', 10, TRUE, '台球散台TV台1台- 中八/追分'),
-- ============ 台球VIP包厢精确匹配============
('VIP包厢', 'BILLIARD_VIP', '台球VIP',
'EXACT', 10, TRUE, '台球VIPVIP包厢4台- V1-V4中八, V5斯诺克'),
-- ============ 斯诺克区(精确匹配)============
('斯诺克区', 'SNOOKER', '斯诺克',
'EXACT', 10, TRUE, '斯诺克斯诺克区4台'),
-- ============ 麻将区(精确匹配)============
('麻将房', 'MAHJONG', '麻将棋牌',
'EXACT', 10, TRUE, '麻将棋牌麻将房5台'),
('M7', 'MAHJONG', '麻将棋牌',
'EXACT', 10, TRUE, '麻将棋牌M72台'),
('M8', 'MAHJONG', '麻将棋牌',
'EXACT', 10, TRUE, '麻将棋牌M81台'),
('666', 'MAHJONG', '麻将棋牌',
'EXACT', 10, TRUE, '麻将棋牌6662台'),
('发财', 'MAHJONG', '麻将棋牌',
'EXACT', 10, TRUE, '麻将棋牌发财1台'),
-- ============ KTV/K包精确匹配============
('K包', 'KTV', 'K歌娱乐',
'EXACT', 10, TRUE, 'K歌娱乐K包4台'),
('k包活动区', 'KTV', 'K歌娱乐',
'EXACT', 10, TRUE, 'K歌娱乐k包活动区2台'),
('幸会158', 'KTV', 'K歌娱乐',
'EXACT', 10, TRUE, 'K歌娱乐幸会1582台'),
-- ============ 特殊区域(精确匹配)============
('补时长', 'SPECIAL', '补时长',
'EXACT', 10, TRUE, '特殊补时长7台- 用于时长补录'),
-- ============ 模糊匹配规则(优先级较低)============
('%VIP%', 'BILLIARD_VIP', '台球VIP',
'LIKE', 50, TRUE, '模糊匹配:包含"VIP"的区域'),
('%斯诺克%', 'SNOOKER', '斯诺克',
'LIKE', 50, TRUE, '模糊匹配:包含"斯诺克"的区域'),
('%麻将%', 'MAHJONG', '麻将棋牌',
'LIKE', 50, TRUE, '模糊匹配:包含"麻将"的区域'),
('%K包%', 'KTV', 'K歌娱乐',
'LIKE', 50, TRUE, '模糊匹配:包含"K包"的区域'),
('%KTV%', 'KTV', 'K歌娱乐',
'LIKE', 50, TRUE, '模糊匹配:包含"KTV"的区域'),
-- ============ 默认兜底(优先级最低)============
('DEFAULT', 'OTHER', '其他',
'DEFAULT', 999, TRUE, '兜底规则:无法匹配的区域归入其他');
-- 台球散台(精确匹配)
('A区', 'BILLIARD', '台球散台', 'EXACT', 10, TRUE, '台球散台A区18台- 中八/追分'),
('B区', 'BILLIARD', '台球散台', 'EXACT', 10, TRUE, '台球散台:B15台)- 中八/追分'),
('C区', 'BILLIARD', '台球散台', 'EXACT', 10, TRUE, '台球散台C区6台- 中八/追分'),
('TV台', 'BILLIARD', '台球散台', 'EXACT', 10, TRUE, '台球散台:TV台1台- 中八/追分'),
-- 台球VIP包厢
('VIP包厢', 'BILLIARD_VIP', '台球VIP', 'EXACT', 10, TRUE, '台球VIPVIP包厢4台- V1-V4中八, V5斯诺克'),
-- 斯诺克区
('斯诺克区', 'SNOOKER', '斯诺克', 'EXACT', 10, TRUE, '斯诺克斯诺克区4台'),
-- 麻将区
('麻将房', 'MAHJONG', '麻将棋牌', 'EXACT', 10, TRUE, '麻将棋牌麻将房5台'),
('M7', 'MAHJONG', '麻将棋牌', 'EXACT', 10, TRUE, '麻将棋牌M72台'),
('M8', 'MAHJONG', '麻将棋牌', 'EXACT', 10, TRUE, '麻将棋牌M81台'),
('666', 'MAHJONG', '麻将棋牌', 'EXACT', 10, TRUE, '麻将棋牌6662台'),
('发财', 'MAHJONG', '麻将棋牌', 'EXACT', 10, TRUE, '麻将棋牌发财1台'),
-- KTV/K包
('K包', 'KTV', 'K歌娱乐', 'EXACT', 10, TRUE, 'K歌娱乐K包4台'),
('k包活动区', 'KTV', 'K歌娱乐', 'EXACT', 10, TRUE, 'K歌娱乐k包活动区2台'),
('幸会158', 'KTV', 'K歌娱乐', 'EXACT', 10, TRUE, 'K歌娱乐幸会1582台'),
-- 特殊区域
('补时长', 'SPECIAL', '补时长', 'EXACT', 10, TRUE, '特殊补时长7台- 用于时长补录'),
-- 模糊匹配规则
('%VIP%', 'BILLIARD_VIP', '台球VIP', 'LIKE', 50, TRUE, '模糊匹配:包含"VIP"的区域'),
('%斯诺克%', 'SNOOKER', '斯诺克', 'LIKE', 50, TRUE, '模糊匹配:包含"斯诺克"的区域'),
('%麻将%', 'MAHJONG', '麻将棋牌', 'LIKE', 50, TRUE, '模糊匹配:包含"麻将"的区域'),
('%K包%', 'KTV', 'K歌娱乐', 'LIKE', 50, TRUE, '模糊匹配:包含"K包"的区域'),
('%KTV%', 'KTV', 'K歌娱乐', 'LIKE', 50, TRUE, '模糊匹配:包含"KTV"的区域'),
-- 默认兜底
('DEFAULT', 'OTHER', '其他', 'DEFAULT', 999, TRUE, '兜底规则:无法匹配的区域归入其他');
-- =============================================================================
@@ -302,63 +258,27 @@ INSERT INTO dws.cfg_area_category (
TRUNCATE TABLE dws.cfg_skill_type RESTART IDENTITY CASCADE;
INSERT INTO dws.cfg_skill_type (
skill_id, skill_name,
skill_id, skill_name,
course_type_code, course_type_name,
is_active, description
) VALUES
-- 基础课/陪打
(2791903611396869, '台球基础陪打',
'BASE', '基础课',
TRUE, '基础课:陪打服务,按助教等级计价'),
-- 附加课/超休
(2807440316432197, '台球超休服务',
'BONUS', '附加课',
TRUE, '附加课:超休/激励课固定190元/小时'),
-- 包厢课(如有)
(2807440316432198, '包厢服务',
'BASE', '基础课',
TRUE, '包厢服务归入基础课统计统一按138元/小时计价');
-- =============================================================================
-- 6. 优惠类型配置(用于财务优惠明细分析)
-- 说明: 定义各类优惠的代码和名称,便于后续分析
-- 6~8. 优惠类型/支出类型/平台类型 — 作为代码常量使用,不单独建表
-- =============================================================================
-- 此配置作为代码常量使用,不单独建表
-- GROUPBUY - 团购优惠
-- VIP - 会员折扣
-- GIFT_CARD - 赠送卡抵扣
-- MANUAL - 手动调整
-- ROUNDING - 抹零
-- BIG_CUSTOMER - 大客户优惠(待抽样分析确认)
-- OTHER - 其他优惠
-- =============================================================================
-- 7. 支出类型配置用于Excel导入
-- 说明: 定义各类支出的代码和名称
-- =============================================================================
-- 此配置作为代码常量使用,不单独建表
-- RENT - 房租
-- UTILITY - 水电费
-- PROPERTY - 物业费
-- SALARY - 工资
-- REIMBURSE - 报销
-- PLATFORM_FEE - 平台服务费
-- OTHER - 其他支出
-- =============================================================================
-- 8. 平台类型配置用于Excel导入
-- 说明: 定义各平台的代码和名称
-- =============================================================================
-- 此配置作为代码常量使用,不单独建表
-- MEITUAN - 美团
-- DOUYIN - 抖音
-- DIANPING - 大众点评
-- OTHER - 其他平台
-- 优惠类型: GROUPBUY/VIP/GIFT_CARD/MANUAL/ROUNDING/BIG_CUSTOMER/OTHER
-- 支出类型: RENT/UTILITY/PROPERTY/SALARY/REIMBURSE/PLATFORM_FEE/OTHER
-- 平台类型: MEITUAN/DOUYIN/DIANPING/OTHER
-- =============================================================================
@@ -377,7 +297,7 @@ BEGIN
SELECT COUNT(*) INTO v_bonus_count FROM dws.cfg_bonus_rules;
SELECT COUNT(*) INTO v_area_count FROM dws.cfg_area_category;
SELECT COUNT(*) INTO v_skill_count FROM dws.cfg_skill_type;
RAISE NOTICE '配置数据初始化完成:';
RAISE NOTICE ' - cfg_performance_tier: % 条', v_tier_count;
RAISE NOTICE ' - cfg_assistant_level_price: % 条', v_price_count;
@@ -386,4 +306,3 @@ BEGIN
RAISE NOTICE ' - cfg_skill_type: % 条', v_skill_count;
END;
$$;
*/

View File

@@ -136,6 +136,54 @@ ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
updated_at = NOW();
-- =============================================================================
-- SPI消费力指数参数
-- 生效时间:北京时间 2026-02-23
-- =============================================================================
INSERT INTO dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
-- 窗口参数
('SPI', 'spend_window_short_days', 30.000000, '短期消费窗口(天)', DATE '2026-02-23'),
('SPI', 'spend_window_long_days', 90.000000, '长期消费窗口(天)', DATE '2026-02-23'),
('SPI', 'ewma_alpha_daily_spend', 0.300000, '日消费 EWMA 平滑系数', DATE '2026-02-23'),
-- 金额压缩基数(基于典型台球门店消费水平的初始默认值)
('SPI', 'amount_base_spend_30', 500.000000, '30天消费额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_spend_90', 1500.000000, '90天消费额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_ticket_90', 200.000000, '90天客单价压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_recharge_90', 1000.000000, '90天充值额压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_speed_abs', 100.000000, '绝对速度压缩基数', DATE '2026-02-23'),
('SPI', 'amount_base_ewma_90', 50.000000, '日消费EWMA压缩基数', DATE '2026-02-23'),
-- Level 子分权重
('SPI', 'w_level_spend_30', 0.300000, 'Level子分30天消费权重', DATE '2026-02-23'),
('SPI', 'w_level_spend_90', 0.350000, 'Level子分90天消费权重', DATE '2026-02-23'),
('SPI', 'w_level_ticket_90', 0.200000, 'Level子分90天客单权重', DATE '2026-02-23'),
('SPI', 'w_level_recharge_90', 0.150000, 'Level子分90天充值权重', DATE '2026-02-23'),
-- Speed 子分权重
('SPI', 'w_speed_abs', 0.500000, 'Speed子分绝对速度权重', DATE '2026-02-23'),
('SPI', 'w_speed_rel', 0.300000, 'Speed子分相对速度权重', DATE '2026-02-23'),
('SPI', 'w_speed_ewma', 0.200000, 'Speed子分EWMA速度权重', DATE '2026-02-23'),
-- 总分权重
('SPI', 'weight_level', 0.600000, 'SPI总分Level子分权重', DATE '2026-02-23'),
('SPI', 'weight_speed', 0.300000, 'SPI总分Speed子分权重', DATE '2026-02-23'),
('SPI', 'weight_stability', 0.100000, 'SPI总分Stability子分权重', DATE '2026-02-23'),
-- 稳定性参数
('SPI', 'stability_window_days', 90.000000, '稳定性计算窗口(天)', DATE '2026-02-23'),
('SPI', 'use_stability', 1.000000, '是否启用稳定性子分0=关闭,1=启用', DATE '2026-02-23'),
-- 映射与平滑
('SPI', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-02-23'),
('SPI', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-02-23'),
('SPI', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-02-23'),
('SPI', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-02-23'),
('SPI', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-02-23'),
-- 速度计算
('SPI', 'speed_epsilon', 0.000001, '速度计算防除零小量', DATE '2026-02-23')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- 验证
-- =============================================================================
@@ -147,6 +195,7 @@ DECLARE
ml_count INTEGER;
nci_count INTEGER;
wbi_count INTEGER;
spi_count INTEGER;
BEGIN
SELECT COUNT(*) INTO rs_count
FROM dws.cfg_index_parameters
@@ -172,12 +221,17 @@ BEGIN
FROM dws.cfg_index_parameters
WHERE index_type = 'WBI';
SELECT COUNT(*) INTO spi_count
FROM dws.cfg_index_parameters
WHERE index_type = 'SPI';
RAISE NOTICE 'RS 参数数量: %', rs_count;
RAISE NOTICE 'OS 参数数量: %', os_count;
RAISE NOTICE 'MS 参数数量: %', ms_count;
RAISE NOTICE 'ML 参数数量: %', ml_count;
RAISE NOTICE '新客转化参数数量: %', nci_count;
RAISE NOTICE '唤回指数参数数量: %', wbi_count;
RAISE NOTICE 'SPI 消费力指数参数数量: %', spi_count;
END $$;
SELECT

View File

@@ -28,8 +28,7 @@ task_codes AS (
'ODS_STORE_GOODS',
'ODS_STORE_GOODS_SALES',
'ODS_TABLE_FEE_DISCOUNT',
'ODS_TENANT_GOODS',
'ODS_SETTLEMENT_TICKET'
'ODS_TENANT_GOODS'
]) AS task_code
)
INSERT INTO meta.etl_task (task_code, store_id, enabled)

View File

@@ -40,6 +40,20 @@ task_codes AS (
'TICKET_DWD',
'TOPUPS',
'DWS_BUILD_ORDER_SUMMARY',
'DWS_ASSISTANT_DAILY',
'DWS_ASSISTANT_MONTHLY',
'DWS_ASSISTANT_CUSTOMER',
'DWS_ASSISTANT_SALARY',
'DWS_ASSISTANT_FINANCE',
'DWS_MEMBER_CONSUMPTION',
'DWS_MEMBER_VISIT',
'DWS_FINANCE_DAILY',
'DWS_FINANCE_RECHARGE',
'DWS_FINANCE_INCOME_STRUCTURE',
'DWS_FINANCE_DISCOUNT_DETAIL',
'DWS_GOODS_STOCK_DAILY',
'DWS_GOODS_STOCK_WEEKLY',
'DWS_GOODS_STOCK_MONTHLY',
'DWS_WINBACK_INDEX',
'DWS_NEWCONV_INDEX',
'DWS_RELATION_INDEX',

View File

@@ -0,0 +1,111 @@
-- =============================================================================
-- FDW 反向映射配置(生产环境)— 在 etl_feiqiu 数据库中执行
-- 用途:通过 postgres_fdw 将 zqyy_app.member_birthday_manual 只读映射到 etl_feiqiu
-- 使 ETL DWS 任务无需直接连接业务库即可读取助教手动补录的会员生日数据。
-- 方向etl_feiqiu → zqyy_app与 setup_fdw.sql 的 zqyy_app → etl_feiqiu 方向相反)
-- 前提zqyy_app 数据库已部署 member_birthday_manual 表(见 C2 迁移脚本)
-- 测试环境版本setup_fdw_reverse_test.sql指向 test_zqyy_app
-- Requirements: 5.3
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 1. 安装 postgres_fdw 扩展(如已安装则跳过)
-- -----------------------------------------------------------------------------
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
-- -----------------------------------------------------------------------------
-- 2. 创建外部服务器(指向 zqyy_app 业务库)
-- 部署时按实际环境替换 host / port
-- -----------------------------------------------------------------------------
CREATE SERVER IF NOT EXISTS zqyy_app_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'zqyy_app', port '5432');
-- -----------------------------------------------------------------------------
-- 3. 创建用户映射(只读角色)
-- etl_user = etl_feiqiu 侧的 ETL 连接角色
-- app_reader = zqyy_app 侧的只读角色
-- 密码占位符 '***',部署时替换为真实凭据
-- -----------------------------------------------------------------------------
CREATE USER MAPPING IF NOT EXISTS FOR etl_user
SERVER zqyy_app_server
OPTIONS (user 'app_reader', password '***');
-- -----------------------------------------------------------------------------
-- 4. 创建目标 schema存放来自业务库的外部表
-- -----------------------------------------------------------------------------
CREATE SCHEMA IF NOT EXISTS fdw_app;
-- -----------------------------------------------------------------------------
-- 5. 创建外部表member_birthday_manual
-- 映射 zqyy_app.public.member_birthday_manualETL 侧只读
-- 列定义须与源表结构保持一致(见 C2 迁移脚本)
-- -----------------------------------------------------------------------------
CREATE FOREIGN TABLE IF NOT EXISTS fdw_app.member_birthday_manual (
id BIGINT,
member_id BIGINT,
birthday_value DATE,
recorded_by_assistant_id BIGINT,
recorded_by_name VARCHAR(50),
recorded_at TIMESTAMPTZ,
source VARCHAR(20),
site_id BIGINT
) SERVER zqyy_app_server
OPTIONS (schema_name 'public', table_name 'member_birthday_manual');
-- -----------------------------------------------------------------------------
-- 6. 授权:允许 etl_user 访问 fdw_app schema 及其外部表
-- -----------------------------------------------------------------------------
GRANT USAGE ON SCHEMA fdw_app TO etl_user;
GRANT SELECT ON ALL TABLES IN SCHEMA fdw_app TO etl_user;
-- 未来新增的外部表自动授权
ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app GRANT SELECT ON TABLES TO etl_user;
-- =============================================================================
-- 回滚脚本(按逆序执行)
-- =============================================================================
-- ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app REVOKE SELECT ON TABLES FROM etl_user;
-- REVOKE SELECT ON ALL TABLES IN SCHEMA fdw_app FROM etl_user;
-- REVOKE USAGE ON SCHEMA fdw_app FROM etl_user;
-- DROP FOREIGN TABLE IF EXISTS fdw_app.member_birthday_manual;
-- DROP SCHEMA IF EXISTS fdw_app CASCADE;
-- DROP USER MAPPING IF EXISTS FOR etl_user SERVER zqyy_app_server;
-- DROP SERVER IF EXISTS zqyy_app_server CASCADE;
-- =============================================================================
-- 验证 SQL
-- =============================================================================
-- 1. 确认外部服务器 zqyy_app_server 存在
-- SELECT srvname, srvowner::regrole, srvoptions
-- FROM pg_foreign_server
-- WHERE srvname = 'zqyy_app_server';
-- 预期1 行srvoptions 包含 dbname=zqyy_app
-- 2. 确认用户映射存在
-- SELECT um.umid, s.srvname, um.umoptions
-- FROM pg_user_mapping um
-- JOIN pg_foreign_server s ON um.umserver = s.oid
-- WHERE s.srvname = 'zqyy_app_server';
-- 预期1 行
-- 3. 确认 fdw_app schema 存在
-- SELECT schema_name
-- FROM information_schema.schemata
-- WHERE schema_name = 'fdw_app';
-- 预期1 行
-- 4. 确认外部表 fdw_app.member_birthday_manual 存在且列完整
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'fdw_app'
-- AND table_name = 'member_birthday_manual'
-- ORDER BY ordinal_position;
-- 预期8 列id, member_id, birthday_value, recorded_by_assistant_id,
-- recorded_by_name, recorded_at, source, site_id
-- 5. 确认外部表可读取(需 zqyy_app 侧表已存在且有网络连通性)
-- SELECT COUNT(*) FROM fdw_app.member_birthday_manual;
-- 预期:返回行数(可能为 0

View File

@@ -0,0 +1,111 @@
-- =============================================================================
-- FDW 反向映射配置(测试环境)— 在 test_etl_feiqiu 数据库中执行
-- 用途:通过 postgres_fdw 将 test_zqyy_app.member_birthday_manual 只读映射到
-- test_etl_feiqiu使 ETL DWS 任务在测试环境下可读取手动补录的会员生日数据。
-- 方向test_etl_feiqiu → test_zqyy_app与 setup_fdw_test.sql 方向相反)
-- 前提test_zqyy_app 数据库已部署 member_birthday_manual 表(见 C2 迁移脚本)
-- 基于 setup_fdw_reverse.sql仅将目标库替换为测试库
-- Requirements: 5.3
-- =============================================================================
-- -----------------------------------------------------------------------------
-- 1. 安装 postgres_fdw 扩展(如已安装则跳过)
-- -----------------------------------------------------------------------------
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
-- -----------------------------------------------------------------------------
-- 2. 创建外部服务器(指向 test_zqyy_app 测试业务库)
-- 部署时按实际环境替换 host / port
-- -----------------------------------------------------------------------------
CREATE SERVER IF NOT EXISTS test_zqyy_app_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'test_zqyy_app', port '5432');
-- -----------------------------------------------------------------------------
-- 3. 创建用户映射(只读角色)
-- etl_user = test_etl_feiqiu 侧的 ETL 连接角色
-- app_reader = test_zqyy_app 侧的只读角色
-- 密码占位符 '***',部署时替换为真实凭据
-- -----------------------------------------------------------------------------
CREATE USER MAPPING IF NOT EXISTS FOR etl_user
SERVER test_zqyy_app_server
OPTIONS (user 'app_reader', password '***');
-- -----------------------------------------------------------------------------
-- 4. 创建目标 schema存放来自业务库的外部表
-- -----------------------------------------------------------------------------
CREATE SCHEMA IF NOT EXISTS fdw_app;
-- -----------------------------------------------------------------------------
-- 5. 创建外部表member_birthday_manual
-- 映射 test_zqyy_app.public.member_birthday_manualETL 侧只读
-- 列定义须与源表结构保持一致(见 C2 迁移脚本)
-- -----------------------------------------------------------------------------
CREATE FOREIGN TABLE IF NOT EXISTS fdw_app.member_birthday_manual (
id BIGINT,
member_id BIGINT,
birthday_value DATE,
recorded_by_assistant_id BIGINT,
recorded_by_name VARCHAR(50),
recorded_at TIMESTAMPTZ,
source VARCHAR(20),
site_id BIGINT
) SERVER test_zqyy_app_server
OPTIONS (schema_name 'public', table_name 'member_birthday_manual');
-- -----------------------------------------------------------------------------
-- 6. 授权:允许 etl_user 访问 fdw_app schema 及其外部表
-- -----------------------------------------------------------------------------
GRANT USAGE ON SCHEMA fdw_app TO etl_user;
GRANT SELECT ON ALL TABLES IN SCHEMA fdw_app TO etl_user;
-- 未来新增的外部表自动授权
ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app GRANT SELECT ON TABLES TO etl_user;
-- =============================================================================
-- 回滚脚本(按逆序执行)
-- =============================================================================
-- ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app REVOKE SELECT ON TABLES FROM etl_user;
-- REVOKE SELECT ON ALL TABLES IN SCHEMA fdw_app FROM etl_user;
-- REVOKE USAGE ON SCHEMA fdw_app FROM etl_user;
-- DROP FOREIGN TABLE IF EXISTS fdw_app.member_birthday_manual;
-- DROP SCHEMA IF EXISTS fdw_app CASCADE;
-- DROP USER MAPPING IF EXISTS FOR etl_user SERVER test_zqyy_app_server;
-- DROP SERVER IF EXISTS test_zqyy_app_server CASCADE;
-- =============================================================================
-- 验证 SQL
-- =============================================================================
-- 1. 确认外部服务器 test_zqyy_app_server 存在
-- SELECT srvname, srvowner::regrole, srvoptions
-- FROM pg_foreign_server
-- WHERE srvname = 'test_zqyy_app_server';
-- 预期1 行srvoptions 包含 dbname=test_zqyy_app
-- 2. 确认用户映射存在
-- SELECT um.umid, s.srvname, um.umoptions
-- FROM pg_user_mapping um
-- JOIN pg_foreign_server s ON um.umserver = s.oid
-- WHERE s.srvname = 'test_zqyy_app_server';
-- 预期1 行
-- 3. 确认 fdw_app schema 存在
-- SELECT schema_name
-- FROM information_schema.schemata
-- WHERE schema_name = 'fdw_app';
-- 预期1 行
-- 4. 确认外部表 fdw_app.member_birthday_manual 存在且列完整
-- SELECT column_name, data_type
-- FROM information_schema.columns
-- WHERE table_schema = 'fdw_app'
-- AND table_name = 'member_birthday_manual'
-- ORDER BY ordinal_position;
-- 预期8 列id, member_id, birthday_value, recorded_by_assistant_id,
-- recorded_by_name, recorded_at, source, site_id
-- 5. 确认外部表可读取(需 test_zqyy_app 侧表已存在且有网络连通性)
-- SELECT COUNT(*) FROM fdw_app.member_birthday_manual;
-- 预期:返回行数(可能为 0

0
db/scripts/.gitkeep Normal file
View File