Appearance
📘 Modelo de Datos Curado para Marketing
SAP → BigQuery → Acoustic Connect
Documento Técnico Completo (Detalle Máximo, Desglose Campo por Campo)
🧠 Objetivo del documento
Este documento describe, con detalle exhaustivo, cómo se construyen todas las vistas del dataset curado mkt_curated, usado en el flujo:
SAP S/4HANA → Replicación Aercorsoft → BigQuery → Acoustic Connect
Incluye:
| Orden | Objeto | Tipo | Propósito |
|---|---|---|---|
| 1 | customers_base_v | Vista | Identidad, contacto y dirección del cliente |
| 2 | customers_sales_v | Vista | Organización comercial del cliente |
| 3 | customers_finance_v | Vista | Condiciones de pago y baja lógica |
| 4 | customers_behavior_fin_v | Vista | Recencia/Frecuencia/Valor en Cuentas por Cobrar (AR) |
| 5 | customers_behavior_deliv_v | Vista | Actividad logística (entregas) |
| 6 | customer_consent | Tabla | Opt-in / consentimiento |
| 7 | acoustic_profiles_v | Vista | Consolidación final para Acoustic Connect |
1️⃣ Vista fundacional: customers_base_v
Consolida identidad, contacto, dirección y fecha de alta de cada cliente SAP.
🔧 SQL
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_base_v` AS
SELECT
SAFE_CAST(k.kunnr AS STRING) AS customer_id,
LOWER(TRIM(a6.smtp_addr)) AS email,
TRIM(k.name1) AS first_name,
TRIM(k.name2) AS last_name,
TRIM(k.telf1) AS phone,
TRIM(addr.nation) AS country,
TRIM(addr.region) AS region,
TRIM(addr.city1) AS city,
TRIM(addr.street) AS address,
SAFE_CAST(k.erdat AS DATE) AS created_at,
IFNULL(k.sperr, '') AS status_raw
FROM `minuto-verde-cortex-poc.CDC_SAP.kna1` k
LEFT JOIN `minuto-verde-cortex-poc.CDC_SAP.adr6` a6
ON a6.addrnumber = k.adrnr
LEFT JOIN `minuto-verde-cortex-poc.CDC_SAP.adrc` addr
ON addr.addrnumber = k.adrnr;
🧩 Explicación de limpieza y estructura (tabla extendida)
| Campo generado | Expresión SQL | Transformación aplicada | Qué evita o mejora | Uso final |
|---|---|---|---|---|
customer_id | SAFE_CAST(k.kunnr AS STRING) | Convierte número SAP a texto seguro | Evita truncamientos y problemas al comparar IDs | Llave en todas las vistas posteriores |
email | LOWER(TRIM(a6.smtp_addr)) | Elimina espacios + fuerza minúsculas | Evita duplicados John@Mail.com ≠ john@mail.com | Llave primaria en Acoustic |
first_name | TRIM(k.name1) | Quita espacios en exceso | SAP guarda "JUAN " | Personalización en campañas |
last_name | TRIM(k.name2) | Limpieza | Personalización / razón social | |
phone | TRIM(k.telf1) | Limpieza | Evita teléfonos ' +56 9 123 ' | Contacto / atributos de perfil |
country/region/city/address | TRIM(addr.…) | Limpieza general | Estándar para CRM / segmentación | Segmentación geográfica |
created_at | SAFE_CAST(k.erdat AS DATE) | Convierte entero SAP a DATE | Permite análisis de recencia | Antigüedad del cliente |
status_raw | IFNULL(k.sperr, '') | Reemplaza nulos | Evita errores al exportar | Indicador de bloqueo SAP |
🧠 Por qué LEFT JOIN
Permite mantener clientes aunque no tengan email ni dirección.
Marketing prefiere registros visibles antes que perderlos.
2️⃣ Vista comercial: customers_sales_v
Expone la estructura comercial del cliente (canal, división, condición de precio).
🔧 SQL
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_sales_v` AS
SELECT
SAFE_CAST(kunnr AS STRING) AS customer_id,
vkorg,
vtweg,
spart,
kdgrp,
konda
FROM `minuto-verde-cortex-poc.CDC_SAP.knvv`;
🧩 Tabla de explicación
| Campo generado | Fuente SAP | Qué significa | Uso en negocio |
|---|---|---|---|
customer_id | KUNNR | ID cliente | Llave para unir con customers_base_v |
vkorg | VKORG | Organización de ventas | Permite segmentación por unidad comercial |
vtweg | VTWEG | Canal de distribución | B2B / B2C / Online / Retail |
spart | SPART | División | Categoría de negocio |
kdgrp | KDGRP | Grupo de clientes | Segmento comercial |
konda | KONDA | Condiciones de precio | Descuentos y pricing |
3️⃣ Vista financiera: customers_finance_v
Define restricciones financieras (condiciones de pago, baja lógica).
🔧 SQL
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_finance_v` AS
SELECT
SAFE_CAST(kunnr AS STRING) AS customer_id,
bukrs,
zterm,
loevm
FROM `minuto-verde-cortex-poc.CDC_SAP.knb1`;
🧩 Tabla de explicación
| Campo | Fuente SAP | Significado | Uso |
|---|---|---|---|
customer_id | KUNNR | ID cliente | Llave |
bukrs | BUKRS | Sociedad / compañía | Filtrar operaciones por país/empresa |
zterm | ZTERM | Condiciones de pago | Segmentar por riesgo / antigüedad |
loevm | LOEVM | Baja lógica | Excluir clientes inactivos |
4️⃣ Vista de comportamiento financiero: customers_behavior_fin_v
Calcula Recencia / Frecuencia / Valor (RFM-like) sobre AR (Accounts Receivable).
🔧 SQL
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_behavior_fin_v` AS
WITH ar AS (
SELECT
SAFE_CAST(bseg.kunnr AS STRING) AS customer_id,
MAX(bkpf.budat) AS last_doc_date,
COUNT(*) AS ar_postings,
SUM(CAST(bseg.dmbtr AS NUMERIC)) AS total_amount_local
FROM `minuto-verde-cortex-poc.CDC_SAP.bseg` bseg
JOIN `minuto-verde-cortex-poc.CDC_SAP.bkpf` bkpf
ON bkpf.bukrs = bseg.bukrs
AND bkpf.gjahr = bseg.gjahr
AND bkpf.belnr = bseg.belnr
WHERE bseg.koart = 'D'
GROUP BY customer_id
)
SELECT * FROM ar;
| Campo | Qué representa | Uso marketing |
|---|---|---|
last_doc_date | Última actividad financiera | Recencia |
ar_postings | Cantidad de movimientos | Frecuencia |
total_amount_local | Acumulado facturado | Valor / LTV |
5️⃣ Vista de comportamiento logístico: customers_behavior_deliv_v
Resume actividad de entregas reales al cliente.
🔧 SQL
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.customers_behavior_deliv_v` AS
WITH deliv AS (
SELECT
SAFE_CAST(likp.kunnr AS STRING) AS customer_id,
MAX(likp.erdat) AS last_delivery_date,
COUNT(DISTINCT likp.vbeln) AS deliveries_count
FROM `minuto-verde-cortex-poc.CDC_SAP.likp`
GROUP BY customer_id
)
SELECT * FROM deliv;
| Campo | Qué representa | Uso |
|---|---|---|
last_delivery_date | Última entrega | Recencia logística |
deliveries_count | Número total de entregas | Frecuencia de consumo |
6️⃣ Tabla materializada: customer_consent
Opt-in / opt-out para contacto (no proviene de SAP).
sql
CREATE OR REPLACE TABLE `minuto-verde-cortex-poc.mkt_curated.customer_consent` (
customer_id STRING NOT NULL,
consent_email BOOL NOT NULL,
consent_date TIMESTAMP,
source_system STRING
);
7️⃣ Vista final consolidada: acoustic_profiles_v
Une todas las vistas previas + consentimiento.
sql
CREATE OR REPLACE VIEW `minuto-verde-cortex-poc.mkt_curated.acoustic_profiles_v` AS
SELECT
b.email AS Email,
b.first_name AS FirstName,
b.last_name AS LastName,
b.customer_id AS CustomerID,
b.phone AS Phone,
b.country, b.region, b.city, b.address,
b.created_at AS CreatedAt,
COALESCE(c.consent_email, FALSE) AS Consent,
c.consent_date AS ConsentDate,
c.source_system AS SourceSystem,
f.last_doc_date AS LastDocDate_AR,
f.ar_postings AS ARPostings,
f.total_amount_local AS TotalAmountLocal,
d.last_delivery_date AS LastDeliveryDate,
d.deliveries_count AS DeliveriesCount
FROM `...customers_base_v` b
LEFT JOIN `...customer_consent` c ON c.customer_id = b.customer_id
LEFT JOIN `...customers_behavior_fin_v` f ON f.customer_id = b.customer_id
LEFT JOIN `...customers_behavior_deliv_v` d ON d.customer_id = b.customer_id;
✅ Resumen Customer 360
| Vista / Tabla | Dimensión aportada |
|---|---|
customers_base_v | Identidad + email + dirección |
customers_sales_v | Organización comercial |
customers_finance_v | Postura financiera |
customers_behavior_fin_v | Recencia/Frecuencia/Valor |
customers_behavior_deliv_v | Logística (entregas) |
customer_consent | Opt-in / privacidad |
acoustic_profiles_v | Exportación final a Acoustic |