fix(modeling): пример витрины в README приведён в соответствие со скриптами
- customer_segment: убрана несуществующая колонка dim_customer, заменена на CASE по сумме (как в 06_dml_dm.sql) - MATERIALIZED VIEW заменён на TRUNCATE + INSERT INTO (как в скриптах), упоминание MV оставлено в ремарке - добавлен комментарий о недетерминированности CURRENT_DATE в bounds Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
-8
@@ -544,11 +544,17 @@ flowchart TD
|
|||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- mart_daily_sales: ежедневные продажи с сегментацией
|
-- mart_daily_sales: ежедневные продажи с сегментацией
|
||||||
CREATE MATERIALIZED VIEW dm.mart_daily_sales AS
|
-- Полная пересборка (full refresh) - для простоты; в продакшене бывает incremental.
|
||||||
|
TRUNCATE dm.mart_daily_sales;
|
||||||
|
|
||||||
|
INSERT INTO dm.mart_daily_sales (
|
||||||
|
date_actual, product_name, customer_segment, total_qty, total_revenue
|
||||||
|
)
|
||||||
SELECT
|
SELECT
|
||||||
d.date_actual AS order_date,
|
d.date_actual,
|
||||||
p.product_name,
|
p.product_name,
|
||||||
c.customer_segment, -- например: 'Premium', 'Basic'
|
-- Сегмент определяем по сумме строки (в реальности может быть атрибутом клиента)
|
||||||
|
CASE WHEN f.amount >= 200 THEN 'Premium' ELSE 'Basic' END AS customer_segment,
|
||||||
SUM(f.quantity) AS total_qty,
|
SUM(f.quantity) AS total_qty,
|
||||||
SUM(f.amount) AS total_revenue
|
SUM(f.amount) AS total_revenue
|
||||||
FROM dds.fact_sales f
|
FROM dds.fact_sales f
|
||||||
@@ -557,13 +563,12 @@ JOIN dds.dim_date d
|
|||||||
JOIN dds.dim_product p
|
JOIN dds.dim_product p
|
||||||
ON f.product_sk = p.product_sk
|
ON f.product_sk = p.product_sk
|
||||||
JOIN dds.dim_customer c
|
JOIN dds.dim_customer c
|
||||||
ON f.customer_sk = c.customer_sk
|
ON f.customer_sk = c.customer_sk -- факт ссылается на нужную версию SK
|
||||||
AND d.date_actual >= c.valid_from
|
GROUP BY d.date_actual, p.product_name,
|
||||||
AND (c.valid_to IS NULL OR d.date_actual < c.valid_to) -- SCD!
|
CASE WHEN f.amount >= 200 THEN 'Premium' ELSE 'Basic' END;
|
||||||
GROUP BY d.date_actual, p.product_name, c.customer_segment;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> 💡 **Материализованное представление (MATERIALIZED VIEW)** — это «кэш» результата. Обновляется по расписанию (например, ночью).
|
> 💡 В продакшене витрину иногда оформляют как **MATERIALIZED VIEW** - «кэш» результата запроса, который обновляется по расписанию. В нашем примере используем обычную таблицу с `TRUNCATE` + `INSERT` - для учебных целей это нагляднее.
|
||||||
|
|
||||||
✏️ **Попробуйте сами:** [Домашка: статусы клиента от STG до DDS (и немного DM)](Homework_Customer_Status_DDS_DM.md) — пройдёте тот же путь, но самостоятельно.
|
✏️ **Попробуйте сами:** [Домашка: статусы клиента от STG до DDS (и немного DM)](Homework_Customer_Status_DDS_DM.md) — пройдёте тот же путь, но самостоятельно.
|
||||||
|
|
||||||
|
|||||||
@@ -311,6 +311,8 @@ WITH bounds AS (
|
|||||||
min(valid_from) AS date_from,
|
min(valid_from) AS date_from,
|
||||||
-- CURRENT_DATE для открытых интервалов (valid_to IS NULL = текущий статус),
|
-- CURRENT_DATE для открытых интервалов (valid_to IS NULL = текущий статус),
|
||||||
-- иначе витрина не покроет даты после последней смены статуса.
|
-- иначе витрина не покроет даты после последней смены статуса.
|
||||||
|
-- Нюанс: количество строк в витрине зависит от даты запуска (каждый
|
||||||
|
-- день добавляется ещё один день). Для учебных целей это приемлемо.
|
||||||
max(coalesce(valid_to, CURRENT_DATE)) AS date_to
|
max(coalesce(valid_to, CURRENT_DATE)) AS date_to
|
||||||
FROM dds.dim_customer_status
|
FROM dds.dim_customer_status
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user