mirror of
https://gitlab.com/cief-data/dbt_cloud.git
synced 2026-08-19 04:14:00 +00:00
Merge branch 'lee_build_rep_frozen_account_incidents' into 'main'
Lee build rep frozen account incidents See merge request cief-data/dbt_cloud!30
This commit is contained in:
@@ -204,6 +204,7 @@ fct_and_dim_joins AS (
|
||||
CASE
|
||||
-- On-time boolean is null when order is not complete
|
||||
WHEN account_verified_payment_datetime IS NULL THEN NULL
|
||||
WHEN estimated_order_delivery_datetime_website_sla IS NULL THEN NULL
|
||||
WHEN estimated_order_delivery_datetime_website_sla > orders.operation_uploaded_bank_slip_datetime THEN 1
|
||||
ELSE 0
|
||||
END AS is_on_time_delivery_website_sla,
|
||||
@@ -212,6 +213,7 @@ fct_and_dim_joins AS (
|
||||
CASE
|
||||
-- On-time boolean is null when order is not complete
|
||||
WHEN account_verified_payment_datetime IS NULL THEN NULL
|
||||
WHEN estimated_order_delivery_datetime_customer_expectation IS NULL THEN NULL
|
||||
WHEN estimated_order_delivery_datetime_customer_expectation > orders.operation_uploaded_bank_slip_datetime THEN 1
|
||||
ELSE 0
|
||||
END AS is_on_time_delivery_customer_expectation,
|
||||
|
||||
@@ -17,7 +17,7 @@ transaction_orders AS (
|
||||
-- LOGIC
|
||||
-- duration_table cte computes the survival time and customer churned indicator
|
||||
duration_table AS (
|
||||
|
||||
|
||||
SELECT
|
||||
companies.company_id, --subject
|
||||
companies.company_created_datetime, -- event start datetime
|
||||
@@ -107,7 +107,6 @@ compute_censored_subjects AS (
|
||||
|
||||
),
|
||||
|
||||
|
||||
compute_probability AS (
|
||||
|
||||
SELECT
|
||||
@@ -115,17 +114,27 @@ compute_probability AS (
|
||||
|
||||
-- The survival probability represents the probability of customers that will not churn up to a specific tenure
|
||||
-- Example: survival_day = 61, survival_prob = 95%. For customers with 61 days of tenure, the customer has a 95% chance of not churning.
|
||||
EXP(SUM(LN(1 - events / at_risk)) OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
)) AS survival_probability,
|
||||
-- When events / at_risk = 1, we replace value 1 with a value very near to 1, to prevent log 0 which causes infinity value
|
||||
EXP(SUM(LN
|
||||
(
|
||||
CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END
|
||||
))
|
||||
OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
)) AS survival_probability,
|
||||
|
||||
100 * (1 - EXP(SUM(LN(1 - events / at_risk)) OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
))) AS conversion_percentage,
|
||||
100 * (1 - EXP(SUM(LN
|
||||
(
|
||||
CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END
|
||||
))
|
||||
OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
))) AS conversion_percentage,
|
||||
|
||||
SUM(events / at_risk) OVER (
|
||||
SUM(events / at_risk)
|
||||
OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
) AS cumulative_hazard,
|
||||
) AS cumulative_hazard,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
-- SOURCE: https://www.holistics.io/blog/calculate-cohort-retention-analysis-with-sql/
|
||||
|
||||
-- IMPORT
|
||||
WITH companies AS (
|
||||
SELECT * FROM {{ ref('dim_shipping__companies') }}
|
||||
),
|
||||
|
||||
origin_warehouse_shipping_packing_lists AS (
|
||||
SELECT * FROM {{ ref('fct_shipping__origin_warehouse_shipping_packing_lists') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
company_register_month_year AS (
|
||||
|
||||
SELECT
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.sub_company_created_datetime,
|
||||
|
||||
IFF(
|
||||
MAX(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime) IS NULL,
|
||||
1,
|
||||
0
|
||||
) AS is_never_order_company,
|
||||
|
||||
DATE(DATE_TRUNC(
|
||||
'MONTH',
|
||||
companies.sub_company_created_datetime
|
||||
)) AS register_month_year,
|
||||
|
||||
DATE(DATE_TRUNC(
|
||||
'MONTH',
|
||||
MIN(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime)
|
||||
)) AS first_order_month_year
|
||||
|
||||
FROM companies
|
||||
|
||||
LEFT JOIN origin_warehouse_shipping_packing_lists
|
||||
ON (companies.sub_company_id = origin_warehouse_shipping_packing_lists.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.sub_company_created_datetime,
|
||||
register_month_year
|
||||
|
||||
),
|
||||
|
||||
company_order_count_from_registration_date AS (
|
||||
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
|
||||
DATEDIFF(
|
||||
MONTH,
|
||||
company_register_month_year.sub_company_created_datetime,
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime
|
||||
) AS order_month
|
||||
|
||||
FROM origin_warehouse_shipping_packing_lists
|
||||
|
||||
LEFT JOIN company_register_month_year
|
||||
ON (origin_warehouse_shipping_packing_lists.sub_company_id = company_register_month_year.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
order_month
|
||||
|
||||
),
|
||||
|
||||
company_first_order_from_registration_date AS (
|
||||
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
DATE(DATE_TRUNC('MONTH', sub_company_created_datetime)) AS sub_company_created_datetime,
|
||||
|
||||
MIN(DATEDIFF(
|
||||
MONTH,
|
||||
company_register_month_year.sub_company_created_datetime,
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime
|
||||
)) AS first_order_month
|
||||
|
||||
FROM origin_warehouse_shipping_packing_lists
|
||||
|
||||
LEFT JOIN company_register_month_year
|
||||
ON (origin_warehouse_shipping_packing_lists.sub_company_id = company_register_month_year.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
sub_company_created_datetime
|
||||
|
||||
),
|
||||
|
||||
cohort_size_by_month_year AS (
|
||||
|
||||
SELECT
|
||||
register_month_year,
|
||||
SUM(is_never_order_company) AS count_never_order_company,
|
||||
COUNT(register_month_year) AS count_total_company
|
||||
|
||||
FROM company_register_month_year
|
||||
|
||||
GROUP BY register_month_year
|
||||
|
||||
ORDER BY register_month_year
|
||||
|
||||
),
|
||||
|
||||
order_retention AS (
|
||||
|
||||
SELECT
|
||||
company_register_month_year.register_month_year,
|
||||
company_order_count_from_registration_date.order_month,
|
||||
COUNT(company_register_month_year.register_month_year) AS count_retained_company
|
||||
|
||||
FROM company_order_count_from_registration_date
|
||||
|
||||
LEFT JOIN company_register_month_year
|
||||
ON (company_order_count_from_registration_date.sub_company_id = company_register_month_year.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
company_register_month_year.register_month_year,
|
||||
company_order_count_from_registration_date.order_month
|
||||
|
||||
),
|
||||
|
||||
first_time_order_retention AS (
|
||||
|
||||
SELECT
|
||||
sub_company_created_datetime,
|
||||
first_order_month,
|
||||
COUNT(first_order_month) AS count_first_order_company
|
||||
|
||||
FROM company_first_order_from_registration_date
|
||||
|
||||
GROUP BY
|
||||
sub_company_created_datetime,
|
||||
first_order_month
|
||||
|
||||
),
|
||||
|
||||
cohort_analysis_table AS (
|
||||
|
||||
SELECT
|
||||
order_retention.register_month_year,
|
||||
order_retention.order_month,
|
||||
order_retention.count_retained_company AS retained_company,
|
||||
|
||||
cohort_size_by_month_year.count_total_company AS total_registered_company,
|
||||
cohort_size_by_month_year.count_never_order_company,
|
||||
|
||||
first_time_order_retention.count_first_order_company AS count_first_order_company,
|
||||
|
||||
DIV0(
|
||||
retained_company,
|
||||
total_registered_company
|
||||
) AS retention_rate_overall,
|
||||
|
||||
DIV0(
|
||||
retained_company,
|
||||
( total_registered_company - cohort_size_by_month_year.count_never_order_company )
|
||||
) AS retention_rate_exclude_never_order_company,
|
||||
|
||||
DIV0(
|
||||
count_first_order_company,
|
||||
( total_registered_company - count_never_order_company )
|
||||
) AS first_order_percentage,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM order_retention
|
||||
|
||||
LEFT JOIN cohort_size_by_month_year
|
||||
ON (order_retention.register_month_year = cohort_size_by_month_year.register_month_year)
|
||||
|
||||
LEFT JOIN first_time_order_retention
|
||||
ON (order_retention.register_month_year = first_time_order_retention.sub_company_created_datetime)
|
||||
AND (order_retention.order_month = first_time_order_retention.first_order_month)
|
||||
|
||||
ORDER BY
|
||||
order_retention.register_month_year,
|
||||
order_retention.order_month
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final_rep_shipping__cohort_analysis AS (
|
||||
|
||||
SELECT
|
||||
-- dimensions
|
||||
register_month_year,
|
||||
total_registered_company,
|
||||
order_month,
|
||||
|
||||
-- measures
|
||||
count_never_order_company,
|
||||
count_first_order_company,
|
||||
retained_company,
|
||||
retention_rate_overall,
|
||||
retention_rate_exclude_never_order_company,
|
||||
first_order_percentage,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM cohort_analysis_table
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final_rep_shipping__cohort_analysis
|
||||
@@ -0,0 +1,236 @@
|
||||
-- AVAILABLE FILTER VALUE
|
||||
{% set day_use_to_churn = 120 %}
|
||||
|
||||
|
||||
-- IMPORT
|
||||
WITH companies AS (
|
||||
SELECT * FROM {{ ref('dim_shipping__companies') }}
|
||||
),
|
||||
|
||||
origin_warehouse_shipping_packing_lists AS (
|
||||
SELECT * FROM {{ ref('fct_shipping__origin_warehouse_shipping_packing_lists') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
remove_supplier_company AS (
|
||||
|
||||
SELECT * FROM companies
|
||||
|
||||
WHERE
|
||||
business_type IN ('IMPORTER', 'ONLINE_SELLER')
|
||||
|
||||
),
|
||||
|
||||
order_date_row_rank AS (
|
||||
|
||||
SELECT
|
||||
*,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY sub_company_id ORDER BY origin_warehouse_shipping_order_created_datetime, origin_warehouse_shipping_packing_list_id
|
||||
) AS row_rank_index
|
||||
|
||||
FROM origin_warehouse_shipping_packing_lists
|
||||
|
||||
),
|
||||
|
||||
get_orders_of_next_and_previous_order_date AS (
|
||||
|
||||
SELECT
|
||||
order_date_row_rank.*,
|
||||
companies.sub_company_created_datetime,
|
||||
companies.sub_company_marking_id,
|
||||
companies.is_migrated_company,
|
||||
previous_order_date_row_rank_clone.origin_warehouse_shipping_order_created_datetime AS previous_order_created_datetime
|
||||
|
||||
FROM order_date_row_rank
|
||||
|
||||
LEFT JOIN companies
|
||||
ON (order_date_row_rank.sub_company_id = companies.sub_company_id)
|
||||
|
||||
LEFT JOIN order_date_row_rank AS next_order_date_row_rank_clone
|
||||
ON (order_date_row_rank.row_rank_index = next_order_date_row_rank_clone.row_rank_index - 1
|
||||
AND order_date_row_rank.sub_company_id = next_order_date_row_rank_clone.sub_company_id)
|
||||
|
||||
LEFT JOIN order_date_row_rank AS previous_order_date_row_rank_clone
|
||||
ON (order_date_row_rank.row_rank_index = previous_order_date_row_rank_clone.row_rank_index + 1
|
||||
AND order_date_row_rank.sub_company_id = previous_order_date_row_rank_clone.sub_company_id)
|
||||
|
||||
),
|
||||
|
||||
-- Register / Churn / Register; Churn
|
||||
company_register_events AS (
|
||||
|
||||
SELECT
|
||||
remove_supplier_company.sub_company_id,
|
||||
remove_supplier_company.sub_company_marking_id,
|
||||
remove_supplier_company.is_migrated_company,
|
||||
remove_supplier_company.sub_company_created_datetime AS event_datetime,
|
||||
'Register' AS register_event,
|
||||
|
||||
IFF(
|
||||
MAX(origin_warehouse_shipping_packing_lists.sub_company_id) IS NULL,
|
||||
1,
|
||||
0
|
||||
) AS is_never_order_company,
|
||||
|
||||
IFF(
|
||||
DATEDIFF(
|
||||
DAY,
|
||||
remove_supplier_company.sub_company_created_datetime,
|
||||
COALESCE(MIN(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime), CURRENT_DATE())
|
||||
) >= {{day_use_to_churn}},
|
||||
'Churn',
|
||||
NULL
|
||||
) AS churn_event,
|
||||
|
||||
RTRIM(
|
||||
CONCAT(
|
||||
CASE WHEN register_event IS NOT NULL THEN 'Register, ' ELSE '' END,
|
||||
CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END
|
||||
),
|
||||
', '
|
||||
) AS concat_event
|
||||
|
||||
FROM remove_supplier_company
|
||||
|
||||
LEFT JOIN origin_warehouse_shipping_packing_lists
|
||||
ON (remove_supplier_company.sub_company_id = origin_warehouse_shipping_packing_lists.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
remove_supplier_company.sub_company_id,
|
||||
remove_supplier_company.sub_company_marking_id,
|
||||
remove_supplier_company.is_migrated_company,
|
||||
remove_supplier_company.sub_company_created_datetime
|
||||
|
||||
),
|
||||
|
||||
-- FirstTimeOrder / Repeat / Churn / Reactive
|
||||
first_time_repeat_churn_reactive_order_events AS (
|
||||
|
||||
SELECT
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
is_migrated_company,
|
||||
0 AS is_never_order_company,
|
||||
origin_warehouse_shipping_packing_list_id,
|
||||
origin_warehouse_shipping_order_status,
|
||||
origin_warehouse_shipping_order_created_datetime AS event_datetime,
|
||||
service_type,
|
||||
total_package_CBM,
|
||||
|
||||
IFF(is_first_time_sub_company = 1, 'First Time Order', NULL) AS first_time_order_event,
|
||||
IFF(is_first_time_sub_company = 0, 'Repeat', NULL) AS repeat_event,
|
||||
IFF(
|
||||
DATEDIFF(
|
||||
DAY,
|
||||
origin_warehouse_shipping_order_created_datetime,
|
||||
COALESCE(next_origin_warehouse_shipping_order_created_datetime, CURRENT_DATE())
|
||||
) >= {{day_use_to_churn}},
|
||||
'Churn',
|
||||
NULL
|
||||
) AS churn_event,
|
||||
|
||||
IFF(
|
||||
DATEDIFF(
|
||||
DAY,
|
||||
COALESCE(previous_order_created_datetime, sub_company_created_datetime),
|
||||
origin_warehouse_shipping_order_created_datetime
|
||||
) >= {{day_use_to_churn}},
|
||||
'Reactive',
|
||||
NULL
|
||||
) AS reactive_event,
|
||||
|
||||
RTRIM(CONCAT(
|
||||
CASE WHEN first_time_order_event IS NOT NULL THEN 'First Time Order, ' ELSE '' END,
|
||||
CASE WHEN repeat_event IS NOT NULL THEN 'Repeat, ' ELSE '' END,
|
||||
CASE WHEN reactive_event IS NOT NULL THEN 'Reactive, ' ELSE '' END,
|
||||
CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END
|
||||
),
|
||||
', '
|
||||
) AS concat_event
|
||||
|
||||
FROM get_orders_of_next_and_previous_order_date
|
||||
),
|
||||
|
||||
union_event_tables AS (
|
||||
|
||||
SELECT
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
is_migrated_company,
|
||||
is_never_order_company,
|
||||
NULL AS origin_warehouse_shipping_packing_list_id,
|
||||
NULL AS origin_warehouse_shipping_order_status,
|
||||
NULL AS service_type,
|
||||
NULL AS total_package_CBM,
|
||||
NULL AS first_time_order_event,
|
||||
NULL AS repeat_event,
|
||||
NULL AS reactive_event,
|
||||
register_event,
|
||||
churn_event,
|
||||
concat_event,
|
||||
event_datetime
|
||||
|
||||
|
||||
FROM company_register_events
|
||||
|
||||
UNION
|
||||
|
||||
SELECT
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
is_migrated_company,
|
||||
is_never_order_company,
|
||||
origin_warehouse_shipping_packing_list_id,
|
||||
origin_warehouse_shipping_order_status,
|
||||
service_type,
|
||||
total_package_CBM,
|
||||
first_time_order_event,
|
||||
repeat_event,
|
||||
reactive_event,
|
||||
NULL AS register_event,
|
||||
churn_event,
|
||||
concat_event,
|
||||
event_datetime
|
||||
|
||||
FROM first_time_repeat_churn_reactive_order_events
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__rep_shipping__company_engagement_behaviors AS (
|
||||
|
||||
SELECT
|
||||
-- id
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
origin_warehouse_shipping_packing_list_id
|
||||
|
||||
-- dimension
|
||||
is_migrated_company,
|
||||
is_never_order_company,
|
||||
origin_warehouse_shipping_order_status,
|
||||
service_type,
|
||||
first_time_order_event,
|
||||
repeat_event,
|
||||
reactive_event,
|
||||
register_event,
|
||||
churn_event,
|
||||
concat_event,
|
||||
|
||||
-- measure
|
||||
total_package_CBM,
|
||||
|
||||
-- date/time
|
||||
event_datetime,
|
||||
|
||||
-- metadata
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM union_event_tables
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__rep_shipping__company_engagement_behaviors
|
||||
@@ -0,0 +1,96 @@
|
||||
-- AVAILABLE FILTER VALUE
|
||||
-- SOURCE: preset_custom_filter Column: day_use_to_churn
|
||||
{% set day_use_to_churn = 120 %}
|
||||
|
||||
-- IMPORT
|
||||
WITH companies AS (
|
||||
SELECT * FROM {{ ref('dim_shipping__companies') }}
|
||||
),
|
||||
|
||||
origin_warehouse_shipping_packing_lists AS (
|
||||
SELECT * FROM {{ ref('fct_shipping__origin_warehouse_shipping_packing_lists') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
company_agg AS (
|
||||
|
||||
SELECT
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.is_migrated_company,
|
||||
companies.sub_company_created_datetime,
|
||||
|
||||
COUNT(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id) AS count_order,
|
||||
MAX(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime) AS last_order_created_datetime,
|
||||
COALESCE(last_order_created_datetime, sub_company_created_datetime) AS last_activity_datetime,
|
||||
|
||||
COUNT(IFF(
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_status IN ('APPROVED', 'COMPLETED'),
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id,
|
||||
null
|
||||
)) AS count_approved_completed_order,
|
||||
|
||||
IFF(MAX(
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime IS NULL
|
||||
), 1, 0
|
||||
) AS is_never_order_company,
|
||||
|
||||
IFF(DATEDIFF(
|
||||
day, last_activity_datetime, CURRENT_DATE()
|
||||
) >= {{day_use_to_churn}},
|
||||
1, 0
|
||||
) AS is_churn_company,
|
||||
|
||||
IFF(is_churn_company = 1,
|
||||
DATEDIFF(day, sub_company_created_datetime, last_activity_datetime) + {{day_use_to_churn}},
|
||||
null
|
||||
) AS create_to_churn_day,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM companies
|
||||
|
||||
LEFT JOIN origin_warehouse_shipping_packing_lists
|
||||
ON (companies.sub_company_id = origin_warehouse_shipping_packing_lists.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.is_migrated_company,
|
||||
companies.sub_company_created_datetime
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__rep_shipping__company_lists AS (
|
||||
|
||||
SELECT
|
||||
-- id
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
|
||||
-- dimensions
|
||||
is_migrated_company,
|
||||
is_never_order_company,
|
||||
is_churn_company,
|
||||
|
||||
-- measures
|
||||
count_order,
|
||||
count_approved_completed_order,
|
||||
create_to_churn_day,
|
||||
|
||||
-- date/time
|
||||
sub_company_created_datetime,
|
||||
last_order_created_datetime,
|
||||
last_activity_datetime,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM company_agg
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__rep_shipping__company_lists
|
||||
@@ -13,9 +13,11 @@ join_tables AS (
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.*,
|
||||
companies.sub_company_marking_id,
|
||||
companies.is_migrated_company,
|
||||
companies.parent_company_id,
|
||||
companies.company_type,
|
||||
companies.state_name AS sub_company_state_name
|
||||
companies.sub_company_created_datetime,
|
||||
companies.state_name AS sub_company_state_name
|
||||
|
||||
FROM (SELECT * EXCLUDE _dbt_ran_datetime FROM origin_warehouse_shipping_packing_lists) AS origin_warehouse_shipping_packing_lists
|
||||
|
||||
@@ -47,6 +49,7 @@ create_metrics AS (
|
||||
FROM join_tables
|
||||
),
|
||||
|
||||
|
||||
--FINAL
|
||||
final__rep_shipping__origin_warehouse_shipping_orders AS (
|
||||
SELECT
|
||||
@@ -70,6 +73,7 @@ final__rep_shipping__origin_warehouse_shipping_orders AS (
|
||||
reference_contract,
|
||||
has_replaced_by_new_origin_warehouse_shipping_packing_list_id,
|
||||
company_type,
|
||||
is_migrated_company,
|
||||
is_first_time_parent_company,
|
||||
is_first_time_parent_company_completed,
|
||||
is_first_time_sub_company,
|
||||
@@ -156,6 +160,7 @@ final__rep_shipping__origin_warehouse_shipping_orders AS (
|
||||
destination_warehouse_transport_number_of_eta_datetime_postpone,
|
||||
|
||||
-- date/times
|
||||
sub_company_created_datetime,
|
||||
booking_created_datetime,
|
||||
delivery_address_created_datetime,
|
||||
billing_address_created_datetime,
|
||||
@@ -187,6 +192,7 @@ final__rep_shipping__origin_warehouse_shipping_orders AS (
|
||||
destination_warehouse_transport_first_estimate_schedule_created_datetime,
|
||||
destination_warehouse_transport_last_estimate_schedule_created_datetime,
|
||||
destination_warehouse_transport_created_datetime,
|
||||
next_origin_warehouse_shipping_order_created_datetime,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
-- AVAILABLE FILTER VALUE
|
||||
-- Alot of companies do not have
|
||||
{% set custom_one_year_from_date = modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")).date() - modules.datetime.timedelta(365) %}
|
||||
{% set custom_one_year_to_date = modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")).date() %}
|
||||
|
||||
-- RFM list values defined using percentile from dashboard [SHIPPING] rfm
|
||||
{% set recency_list_lifetime = [120,240,360,480] %}
|
||||
{% set frequency_list_lifetime = [1,2,8,24] %}
|
||||
{% set monetary_list_lifetime = [0.74,3.01,7.87,27.27] %}
|
||||
|
||||
{% set recency_list_one_year = [120,240,360,480] %}
|
||||
{% set frequency_list_one_year = [1,2,7,16] %}
|
||||
{% set monetary_list_one_year = [0.76,3.00,7.36,22.80] %}
|
||||
|
||||
|
||||
-- IMPORT
|
||||
WITH origin_warehouse_shipping_packing_lists AS (
|
||||
SELECT * FROM {{ ref('fct_shipping__origin_warehouse_shipping_packing_lists') }}
|
||||
),
|
||||
|
||||
companies AS (
|
||||
SELECT * FROM {{ ref('dim_shipping__companies') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
company_shipping_order_one_year AS(
|
||||
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
COUNT(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id) AS number_of_packing_list_one_year,
|
||||
MAX(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime) AS last_packing_list_created_datetime_one_year,
|
||||
DATEDIFF(day, last_packing_list_created_datetime_one_year, CURRENT_DATE()) AS day_after_last_packing_list_one_year,
|
||||
SUM(origin_warehouse_shipping_packing_lists.total_package_cbm) AS total_package_cbm_one_year
|
||||
|
||||
FROM origin_warehouse_shipping_packing_lists
|
||||
|
||||
LEFT JOIN companies
|
||||
ON (origin_warehouse_shipping_packing_lists.sub_company_id = companies.sub_company_id)
|
||||
|
||||
WHERE
|
||||
origin_warehouse_shipping_order_status IN ('COMPLETED','APPROVED')
|
||||
AND
|
||||
origin_warehouse_shipping_order_created_datetime >= '{{ custom_one_year_from_date }}'
|
||||
AND
|
||||
origin_warehouse_shipping_order_created_datetime < '{{ custom_one_year_to_date }}'
|
||||
|
||||
GROUP BY
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
companies.sub_company_marking_id
|
||||
|
||||
),
|
||||
|
||||
company_rfm AS (
|
||||
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
|
||||
MAX(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime) AS last_packing_list_created_datetime,
|
||||
|
||||
DATEDIFF(day, last_packing_list_created_datetime, CURRENT_DATE() ) AS day_after_last_packing_list_lifetime,
|
||||
MAX(company_shipping_order_one_year.day_after_last_packing_list_one_year) AS day_after_last_packing_list_one_year,
|
||||
|
||||
COUNT(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id) AS number_of_packing_list_lifetime,
|
||||
MAX(company_shipping_order_one_year.number_of_packing_list_one_year) AS number_of_packing_list_one_year,
|
||||
|
||||
SUM(origin_warehouse_shipping_packing_lists.total_package_cbm) AS total_package_cbm_lifetime,
|
||||
MAX(company_shipping_order_one_year.total_package_cbm_one_year) AS total_package_cbm_one_year
|
||||
|
||||
FROM origin_warehouse_shipping_packing_lists
|
||||
|
||||
LEFT JOIN company_shipping_order_one_year
|
||||
ON (origin_warehouse_shipping_packing_lists.sub_company_id = company_shipping_order_one_year.sub_company_id)
|
||||
|
||||
LEFT JOIN companies
|
||||
ON (origin_warehouse_shipping_packing_lists.sub_company_id = companies.sub_company_id)
|
||||
|
||||
WHERE
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_status IN ('COMPLETED','APPROVED')
|
||||
|
||||
GROUP BY
|
||||
origin_warehouse_shipping_packing_lists.sub_company_id,
|
||||
companies.sub_company_marking_id
|
||||
|
||||
),
|
||||
|
||||
calculate_rfm AS (
|
||||
|
||||
SELECT
|
||||
*,
|
||||
|
||||
CASE
|
||||
WHEN day_after_last_packing_list_lifetime <= {{recency_list_lifetime[0]}} THEN 5
|
||||
WHEN (day_after_last_packing_list_lifetime > {{recency_list_lifetime[0]}} AND day_after_last_packing_list_lifetime <= {{recency_list_lifetime[1]}}) THEN 4
|
||||
WHEN (day_after_last_packing_list_lifetime > {{recency_list_lifetime[1]}} AND day_after_last_packing_list_lifetime <= {{recency_list_lifetime[2]}}) THEN 3
|
||||
WHEN (day_after_last_packing_list_lifetime > {{recency_list_lifetime[2]}} AND day_after_last_packing_list_lifetime <= {{recency_list_lifetime[3]}}) THEN 2
|
||||
WHEN day_after_last_packing_list_lifetime > {{recency_list_lifetime[3]}} THEN 1
|
||||
ELSE -999
|
||||
END AS r_score_lifetime,
|
||||
|
||||
CASE
|
||||
WHEN number_of_packing_list_lifetime <= {{frequency_list_lifetime[0]}} THEN 1
|
||||
WHEN (number_of_packing_list_lifetime > {{frequency_list_lifetime[0]}} AND number_of_packing_list_lifetime <= {{frequency_list_lifetime[1]}}) THEN 2
|
||||
WHEN (number_of_packing_list_lifetime > {{frequency_list_lifetime[1]}} AND number_of_packing_list_lifetime <= {{frequency_list_lifetime[2]}}) THEN 3
|
||||
WHEN (number_of_packing_list_lifetime > {{frequency_list_lifetime[2]}} AND number_of_packing_list_lifetime <= {{frequency_list_lifetime[3]}}) THEN 4
|
||||
WHEN number_of_packing_list_lifetime > {{frequency_list_lifetime[3]}} THEN 5
|
||||
ELSE -999
|
||||
END AS f_score_lifetime,
|
||||
|
||||
CASE
|
||||
WHEN total_package_cbm_lifetime <= {{monetary_list_lifetime[0]}} THEN 1
|
||||
WHEN (total_package_cbm_lifetime > {{monetary_list_lifetime[0]}} AND total_package_cbm_lifetime <= {{monetary_list_lifetime[1]}}) THEN 2
|
||||
WHEN (total_package_cbm_lifetime > {{monetary_list_lifetime[1]}} AND total_package_cbm_lifetime <= {{monetary_list_lifetime[2]}}) THEN 3
|
||||
WHEN (total_package_cbm_lifetime > {{monetary_list_lifetime[2]}} AND total_package_cbm_lifetime <= {{monetary_list_lifetime[3]}}) THEN 4
|
||||
WHEN total_package_cbm_lifetime > {{monetary_list_lifetime[3]}} THEN 5
|
||||
ELSE -999
|
||||
END AS m_score_lifetime,
|
||||
|
||||
CASE
|
||||
WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 5) AND (m_score_lifetime = 5)
|
||||
THEN '1_King'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1)
|
||||
THEN '10_At Cheap Risk'
|
||||
|
||||
WHEN (r_score_lifetime = 1) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1)
|
||||
THEN '13_Cheap Lost'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime BETWEEN 4 AND 5)
|
||||
THEN '4_Whale'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 2)
|
||||
THEN '3_Sardine'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5)
|
||||
THEN '2_Loyal Customer'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 2 AND 5) AND (m_score_lifetime BETWEEN 2 AND 5)
|
||||
THEN '5_Potention Loyal'
|
||||
|
||||
WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2)
|
||||
THEN '7_New Customer'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5)
|
||||
THEN '8_At High Risk'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5)
|
||||
THEN '9_At Risk'
|
||||
WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2)
|
||||
THEN '9_At Risk'
|
||||
WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime = 1)
|
||||
THEN '9_At Risk'
|
||||
|
||||
WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
|
||||
WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime BETWEEN 1 AND 3)
|
||||
THEN '12_Lost'
|
||||
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 3)
|
||||
THEN '6_Normal Customer'
|
||||
WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime = 1)
|
||||
THEN '6_Normal Customer'
|
||||
|
||||
ELSE 'ERROR Please Contact DATA Team'
|
||||
END AS segment_lifetime,
|
||||
|
||||
CASE
|
||||
WHEN day_after_last_packing_list_one_year IS NULL THEN NULL
|
||||
WHEN day_after_last_packing_list_one_year <= {{recency_list_one_year[0]}} THEN 5
|
||||
WHEN (day_after_last_packing_list_one_year > {{recency_list_one_year[0]}} AND day_after_last_packing_list_one_year <= {{recency_list_one_year[1]}}) THEN 4
|
||||
WHEN (day_after_last_packing_list_one_year > {{recency_list_one_year[1]}} AND day_after_last_packing_list_one_year <= {{recency_list_one_year[2]}}) THEN 3
|
||||
WHEN (day_after_last_packing_list_one_year > {{recency_list_one_year[2]}} AND day_after_last_packing_list_one_year <= {{recency_list_one_year[3]}}) THEN 2
|
||||
WHEN day_after_last_packing_list_one_year > {{recency_list_one_year[3]}} THEN 1
|
||||
ELSE -999
|
||||
END AS r_score_one_year,
|
||||
|
||||
CASE
|
||||
WHEN number_of_packing_list_one_year IS NULL THEN NULL
|
||||
WHEN number_of_packing_list_one_year <= {{frequency_list_one_year[0]}} THEN 1
|
||||
WHEN (number_of_packing_list_one_year > {{frequency_list_one_year[0]}} AND number_of_packing_list_one_year <= {{frequency_list_one_year[1]}}) THEN 2
|
||||
WHEN (number_of_packing_list_one_year > {{frequency_list_one_year[1]}} AND number_of_packing_list_one_year <= {{frequency_list_one_year[2]}}) THEN 3
|
||||
WHEN (number_of_packing_list_one_year > {{frequency_list_one_year[2]}} AND number_of_packing_list_one_year <= {{frequency_list_one_year[3]}}) THEN 4
|
||||
WHEN number_of_packing_list_one_year > {{frequency_list_one_year[3]}} THEN 5
|
||||
ELSE -999
|
||||
END AS f_score_one_year,
|
||||
|
||||
CASE
|
||||
WHEN total_package_cbm_one_year IS NULL THEN NULL
|
||||
WHEN total_package_cbm_one_year <= {{monetary_list_one_year[0]}} THEN 1
|
||||
WHEN (total_package_cbm_one_year > {{monetary_list_one_year[0]}} AND total_package_cbm_one_year <= {{monetary_list_one_year[1]}}) THEN 2
|
||||
WHEN (total_package_cbm_one_year > {{monetary_list_one_year[1]}} AND total_package_cbm_one_year <= {{monetary_list_one_year[2]}}) THEN 3
|
||||
WHEN (total_package_cbm_one_year > {{monetary_list_one_year[2]}} AND total_package_cbm_one_year <= {{monetary_list_one_year[3]}}) THEN 4
|
||||
WHEN total_package_cbm_one_year > {{monetary_list_one_year[3]}} THEN 5
|
||||
ELSE -999
|
||||
END AS m_score_one_year,
|
||||
|
||||
CASE
|
||||
WHEN (r_score_one_year IS NULL) AND (f_score_one_year IS NULL) AND (m_score_one_year IS NULL)
|
||||
THEN '14_Not Active Between 1 year'
|
||||
|
||||
WHEN (r_score_one_year = 5) AND (f_score_one_year = 5) AND (m_score_one_year = 5)
|
||||
THEN '1_King'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year = 1)
|
||||
THEN '10_At Cheap Risk'
|
||||
|
||||
WHEN (r_score_one_year = 1) AND (f_score_one_year = 1) AND (m_score_one_year = 1)
|
||||
THEN '13_Cheap Lost'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year BETWEEN 4 AND 5)
|
||||
THEN '4_Whale'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 2)
|
||||
THEN '3_Sardine'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5)
|
||||
THEN '2_Loyal Customer'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 2 AND 5) AND (m_score_one_year BETWEEN 2 AND 5)
|
||||
THEN '5_Potention Loyal'
|
||||
|
||||
WHEN (r_score_one_year = 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2)
|
||||
THEN '7_New Customer'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 4 AND 5)
|
||||
THEN '8_At High Risk'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 1 AND 5)
|
||||
THEN '9_At Risk'
|
||||
WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2)
|
||||
THEN '9_At Risk'
|
||||
WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year = 1)
|
||||
THEN '9_At Risk'
|
||||
|
||||
WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 4 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5)
|
||||
THEN '11_Cant Lose Them'
|
||||
|
||||
WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year BETWEEN 1 AND 3)
|
||||
THEN '12_Lost'
|
||||
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 3)
|
||||
THEN '6_Normal Customer'
|
||||
WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year = 1)
|
||||
THEN '6_Normal Customer'
|
||||
|
||||
ELSE 'ERROR Please Contact DATA Team'
|
||||
END AS segment_one_year,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM company_rfm
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__rep_shipping__rfm AS (
|
||||
|
||||
SELECT
|
||||
-- ids
|
||||
sub_company_id,
|
||||
sub_company_marking_id,
|
||||
|
||||
-- dimensions
|
||||
segment_lifetime,
|
||||
segment_one_year,
|
||||
|
||||
-- measures
|
||||
day_after_last_packing_list_lifetime,
|
||||
number_of_packing_list_lifetime,
|
||||
total_package_cbm_lifetime,
|
||||
r_score_lifetime,
|
||||
f_score_lifetime,
|
||||
m_score_lifetime,
|
||||
day_after_last_packing_list_one_year,
|
||||
number_of_packing_list_one_year,
|
||||
total_package_cbm_one_year,
|
||||
r_score_one_year,
|
||||
f_score_one_year,
|
||||
m_score_one_year,
|
||||
|
||||
-- date/times
|
||||
last_packing_list_created_datetime,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM calculate_rfm
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__rep_shipping__rfm
|
||||
@@ -0,0 +1,183 @@
|
||||
-- Survival analysis code reference from https://www.crosstab.io/articles/sql-survival-curves/
|
||||
|
||||
-- AVAILABLE FILTER VALUE
|
||||
-- Source:preset_custom_filter Column:day_use_to_churn
|
||||
{% set day_use_to_churn = 120 %}
|
||||
|
||||
|
||||
-- IMPORT
|
||||
WITH companies AS (
|
||||
SELECT * FROM {{ ref('dim_shipping__companies') }}
|
||||
),
|
||||
|
||||
origin_warehouse_shipping_packing_lists AS (
|
||||
SELECT * FROM {{ ref('fct_shipping__origin_warehouse_shipping_packing_lists') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
duration_table AS (
|
||||
|
||||
SELECT
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.sub_company_created_datetime,
|
||||
COUNT(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id) AS count_order,
|
||||
|
||||
COUNT(IFF(
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_status IN ('APPROVED', 'COMPLETED'),
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id,
|
||||
null
|
||||
)) AS count_completed_order,
|
||||
|
||||
MAX(origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_order_created_datetime) AS last_order_datetime,
|
||||
COALESCE(last_order_datetime, sub_company_created_datetime) AS last_activity_datetime,
|
||||
IFF(last_order_datetime IS NULL, 1, 0) AS is_never_order_company,
|
||||
|
||||
-- if is_churn_company = 0, the data will be censored
|
||||
IFF(
|
||||
DATEDIFF(day, last_activity_datetime, CURRENT_DATE()) >= {{day_use_to_churn}},
|
||||
1,
|
||||
0
|
||||
) AS is_churn_company,
|
||||
|
||||
CASE
|
||||
WHEN is_churn_company = 1 THEN
|
||||
DATEDIFF(day, companies.sub_company_created_datetime, last_activity_datetime) + {{day_use_to_churn}}
|
||||
ELSE
|
||||
DATEDIFF(day, companies.sub_company_created_datetime, CURRENT_DATE())
|
||||
END AS survival_time_days --event duration
|
||||
|
||||
FROM companies
|
||||
|
||||
LEFT JOIN origin_warehouse_shipping_packing_lists
|
||||
ON (companies.sub_company_id = origin_warehouse_shipping_packing_lists.sub_company_id)
|
||||
|
||||
GROUP BY
|
||||
companies.sub_company_id,
|
||||
companies.sub_company_marking_id,
|
||||
companies.sub_company_created_datetime
|
||||
|
||||
HAVING
|
||||
-- companies without order will not be relevant to the analysis
|
||||
is_never_order_company = 0
|
||||
|
||||
),
|
||||
|
||||
-- the daily_tally cte count the total number of observations at each survival_time_day
|
||||
-- and the number of company that have churned at that survival_time_day
|
||||
daily_observation_tally AS (
|
||||
|
||||
SELECT
|
||||
survival_time_days,
|
||||
COUNT(survival_time_days) AS total_number_of_observations,
|
||||
SUM(is_churn_company) AS events -- considering only churned company
|
||||
|
||||
FROM duration_table
|
||||
|
||||
GROUP BY survival_time_days
|
||||
|
||||
ORDER BY survival_time_days
|
||||
|
||||
),
|
||||
|
||||
-- the cumulative_tally cte counts the number of subjects still at risk of experiencing churn
|
||||
cumulative_tally AS (
|
||||
|
||||
SELECT
|
||||
survival_time_days,
|
||||
events,
|
||||
total_number_of_observations,
|
||||
|
||||
( SELECT COUNT(DISTINCT(sub_company_id)) FROM duration_table ) AS total_number_of_subjects,
|
||||
|
||||
-- cumulative sum of observations at all previous survival_time_days SUBTRACTED by total_number_of_subjects
|
||||
total_number_of_subjects - COALESCE(
|
||||
SUM(total_number_of_observations) OVER (ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
|
||||
,0
|
||||
) AS at_risk
|
||||
|
||||
FROM daily_observation_tally
|
||||
|
||||
),
|
||||
|
||||
-- At each survival_time_day, count number of censored subject
|
||||
-- censored subjects = # subject at risk - churned - # subject at risk in the next duration
|
||||
compute_censored_subjects AS (
|
||||
|
||||
SELECT
|
||||
total_number_of_subjects,
|
||||
survival_time_days,
|
||||
at_risk,
|
||||
total_number_of_observations,
|
||||
events,
|
||||
at_risk - events - COALESCE(
|
||||
LEAD(at_risk, 1) OVER (ORDER BY survival_time_days)
|
||||
,0
|
||||
) AS censored
|
||||
|
||||
FROM cumulative_tally
|
||||
|
||||
-- Simply subtracting events from number of observations would incorrectly ignore subjects censored at durations that are dropped from the output table
|
||||
WHERE events > 0
|
||||
|
||||
),
|
||||
|
||||
compute_probability AS (
|
||||
|
||||
SELECT
|
||||
*,
|
||||
-- The survival probability represents the probability of customers that will not churn up to a specific tenure
|
||||
-- Example: survival_day = 96, survival_prob = 95%. For customers with 96 days of tenure, the customer has a 95% chance of not churning.
|
||||
EXP(SUM(
|
||||
-- When events / at_risk = 1, we replace value 1 with a value close to 1, to prevent log 0 which causes infinity value
|
||||
LN(CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END)
|
||||
) OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
)
|
||||
) AS survival_probability,
|
||||
|
||||
100 * (1 - EXP(SUM(
|
||||
-- When events / at_risk = 1, we replace value 1 with a value close to 1, to prevent log 0 which causes infinity value
|
||||
LN(CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END)
|
||||
) OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
)
|
||||
)) AS conversion_percentage,
|
||||
|
||||
SUM(events / at_risk)
|
||||
OVER (
|
||||
ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
) AS cumulative_hazard,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM compute_censored_subjects
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__rep_shipping__survival_analysis AS (
|
||||
|
||||
SELECT
|
||||
-- dimension
|
||||
survival_time_days,
|
||||
at_risk,
|
||||
total_number_of_observations,
|
||||
events,
|
||||
censored,
|
||||
|
||||
-- measures
|
||||
survival_probability,
|
||||
conversion_percentage,
|
||||
cumulative_hazard,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM compute_probability
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__rep_shipping__survival_analysis
|
||||
@@ -14,18 +14,19 @@ company_documents AS (
|
||||
|
||||
-- LOGIC
|
||||
latest_company_documents AS (
|
||||
|
||||
SELECT
|
||||
document_id AS identity_document_id,
|
||||
parent_company_id AS identity_parent_company_id,
|
||||
approver_user_id AS identity_approver_user_id,
|
||||
status AS identity_status,
|
||||
document_type AS identity_document_type,
|
||||
identity_number AS identity_identity_number,
|
||||
approved_datetime AS identity_approved_datetime,
|
||||
deleted_datetime AS identity_deleted_datetime,
|
||||
created_datetime AS identity_created_datetime,
|
||||
updated_datetime AS identity_updated_datetime,
|
||||
row_number() OVER
|
||||
document_id AS identity_document_id,
|
||||
parent_company_id AS identity_parent_company_id,
|
||||
approver_user_id AS identity_approver_user_id,
|
||||
status AS identity_status,
|
||||
document_type AS identity_document_type,
|
||||
identity_number AS identity_identity_number,
|
||||
approved_datetime AS identity_approved_datetime,
|
||||
deleted_datetime AS identity_deleted_datetime,
|
||||
created_datetime AS identity_created_datetime,
|
||||
updated_datetime AS identity_updated_datetime,
|
||||
ROW_NUMBER() OVER
|
||||
(PARTITION BY parent_company_id
|
||||
ORDER BY created_datetime DESC) AS latest_row_number
|
||||
|
||||
@@ -36,15 +37,19 @@ latest_company_documents AS (
|
||||
|
||||
QUALIFY
|
||||
latest_row_number = 1
|
||||
|
||||
),
|
||||
|
||||
sub_companies_enrich AS (
|
||||
|
||||
SELECT
|
||||
parent_and_sub_companies.parent_company_id,
|
||||
parent_and_sub_companies.autocount_id,
|
||||
parent_and_sub_companies.sub_company_id,
|
||||
parent_and_sub_companies.sub_company_marking_id,
|
||||
parent_and_sub_companies.status AS sub_company_status,
|
||||
parent_and_sub_companies.status AS sub_company_status,
|
||||
parent_and_sub_companies.is_credit_term_company,
|
||||
parent_and_sub_companies.is_migrated_company,
|
||||
parent_and_sub_companies.parent_company_name,
|
||||
parent_and_sub_companies.sub_company_name,
|
||||
parent_and_sub_companies.company_type,
|
||||
@@ -64,9 +69,9 @@ sub_companies_enrich AS (
|
||||
latest_sub_company_billing_addresses.postcode,
|
||||
latest_sub_company_billing_addresses.address_type,
|
||||
latest_sub_company_billing_addresses.is_default_address,
|
||||
latest_sub_company_billing_addresses.status AS company_address_status,
|
||||
latest_sub_company_billing_addresses.created_datetime AS company_addresses_created_datetime,
|
||||
latest_sub_company_billing_addresses.updated_datetime AS company_addresses_updated_datetime,
|
||||
latest_sub_company_billing_addresses.status AS company_address_status,
|
||||
latest_sub_company_billing_addresses.created_datetime AS company_addresses_created_datetime,
|
||||
latest_sub_company_billing_addresses.updated_datetime AS company_addresses_updated_datetime,
|
||||
|
||||
latest_company_documents.identity_document_id,
|
||||
latest_company_documents.identity_approver_user_id,
|
||||
@@ -87,10 +92,13 @@ sub_companies_enrich AS (
|
||||
|
||||
LEFT JOIN latest_company_documents
|
||||
ON (parent_and_sub_companies.parent_company_id = latest_company_documents.identity_parent_company_id)
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__dim_shipping__companies AS (
|
||||
|
||||
SELECT
|
||||
-- ids
|
||||
sub_company_id,
|
||||
@@ -107,6 +115,8 @@ final__dim_shipping__companies AS (
|
||||
sub_company_name,
|
||||
company_type,
|
||||
business_type,
|
||||
is_credit_term_company,
|
||||
is_migrated_company,
|
||||
company_address_status,
|
||||
address_reference,
|
||||
address_line_one,
|
||||
@@ -138,8 +148,8 @@ final__dim_shipping__companies AS (
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
|
||||
FROM sub_companies_enrich
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__dim_shipping__companies
|
||||
@@ -33,20 +33,20 @@ origin_warehouse_shipping_packing_lists_enrich AS (
|
||||
SELECT
|
||||
origin_warehouse_shipping_packing_lists.origin_warehouse_shipping_packing_list_id,
|
||||
origin_warehouse_shipping_packing_lists.old_origin_warehouse_shipping_packing_list_id,
|
||||
origin_warehouse_shipping_packing_lists.has_replaced_by_new_id AS has_replaced_by_new_origin_warehouse_shipping_packing_list_id,
|
||||
origin_warehouse_shipping_packing_lists.has_replaced_by_new_id AS has_replaced_by_new_origin_warehouse_shipping_packing_list_id,
|
||||
|
||||
origin_warehouse_shipping_packing_lists.warehouse_order_number AS warehouse_order_number,
|
||||
origin_warehouse_shipping_packing_lists.warehouse_order_number AS warehouse_order_number,
|
||||
|
||||
origin_warehouse_shipping_packing_lists.warehouse_sub_company_id,
|
||||
origin_warehouse_shipping_packing_lists.reference_contract,
|
||||
origin_warehouse_shipping_packing_lists.status AS origin_warehouse_shipping_order_status,
|
||||
origin_warehouse_shipping_packing_lists.created_datetime AS origin_warehouse_shipping_order_created_datetime,
|
||||
origin_warehouse_shipping_packing_lists.status AS origin_warehouse_shipping_order_status,
|
||||
origin_warehouse_shipping_packing_lists.created_datetime AS origin_warehouse_shipping_order_created_datetime,
|
||||
|
||||
origin_warehouse_shipping_packing_lists.booking_id,
|
||||
bookings.sub_company_id,
|
||||
bookings.service_type,
|
||||
bookings.status AS booking_status,
|
||||
bookings.created_datetime AS booking_created_datetime,
|
||||
bookings.status AS booking_status,
|
||||
bookings.created_datetime AS booking_created_datetime,
|
||||
|
||||
booking_delivery_and_billing_addresses.delivery_address_reference,
|
||||
booking_delivery_and_billing_addresses.delivery_address_line_one,
|
||||
@@ -204,6 +204,10 @@ create_new_column AS (
|
||||
THEN 1
|
||||
ELSE 0
|
||||
END AS is_first_time_sub_company_completed,
|
||||
|
||||
LEAD(origin_warehouse_shipping_order_created_datetime) OVER (
|
||||
PARTITION BY sub_company_id ORDER BY (origin_warehouse_shipping_order_created_datetime, CAST(origin_warehouse_shipping_packing_list_id AS INT))
|
||||
) AS next_origin_warehouse_shipping_order_created_datetime,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
@@ -345,6 +349,7 @@ final__fct_shipping__origin_warehouse_shipping_packing_lists AS (
|
||||
destination_warehouse_transport_first_estimate_schedule_created_datetime,
|
||||
destination_warehouse_transport_last_estimate_schedule_created_datetime,
|
||||
destination_warehouse_transport_created_datetime,
|
||||
next_origin_warehouse_shipping_order_created_datetime,
|
||||
|
||||
-- metadata
|
||||
_dbt_ran_datetime
|
||||
|
||||
@@ -3,19 +3,23 @@ WITH company_connections AS (
|
||||
SELECT * FROM {{ source('src_shipping_mysql', 'company_connections') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
company_connections_rename AS (
|
||||
|
||||
SELECT
|
||||
company_connections.id AS sub_company_marking_connection_id,
|
||||
company_connections.invitee_id AS sub_company_id,
|
||||
company_connections.id AS sub_company_marking_connection_id,
|
||||
company_connections.invitee_id AS sub_company_id,
|
||||
company_connections.invitee_reference AS sub_company_marking_id,
|
||||
company_connections.status,
|
||||
company_connections.created_at AS created_datetime,
|
||||
company_connections.updated_at AS updated_datetime,
|
||||
company_connections.is_credit_term AS is_credit_term_company,
|
||||
company_connections.created_at AS created_datetime,
|
||||
company_connections.updated_at AS updated_datetime,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM company_connections
|
||||
|
||||
),
|
||||
|
||||
|
||||
@@ -30,6 +34,7 @@ final__base_shipping__sub_company_marking_connections AS (
|
||||
|
||||
-- dimensions
|
||||
status,
|
||||
is_credit_term_company,
|
||||
|
||||
-- measures
|
||||
|
||||
@@ -41,6 +46,7 @@ final__base_shipping__sub_company_marking_connections AS (
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM company_connections_rename
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__base_shipping__sub_company_marking_connections
|
||||
@@ -26,23 +26,27 @@ status AS (
|
||||
WHERE category = 'DEFAULT'
|
||||
),
|
||||
|
||||
migrated_sub_company_marking_id AS (
|
||||
SELECT * FROM {{ ref('seed_shipping__migrated_company_marking_id') }}
|
||||
),
|
||||
|
||||
|
||||
-- LOGIC
|
||||
parent_companies_join_sub_companies AS (
|
||||
SELECT
|
||||
parent_companies.parent_company_id AS parent_company_id,
|
||||
parent_companies.parent_company_id AS parent_company_id,
|
||||
parent_companies.autocount_id,
|
||||
parent_companies.name AS parent_company_name,
|
||||
parent_companies.name AS parent_company_name,
|
||||
parent_companies.parent_company_type AS company_type,
|
||||
parent_companies.status,
|
||||
parent_companies.created_datetime AS parent_company_created_datetime,
|
||||
parent_companies.updated_datetime AS parent_company_updated_datetime,
|
||||
parent_companies.created_datetime AS parent_company_created_datetime,
|
||||
parent_companies.updated_datetime AS parent_company_updated_datetime,
|
||||
|
||||
sub_companies.sub_company_id AS sub_company_id,
|
||||
sub_companies.name AS sub_company_name,
|
||||
sub_companies.sub_company_type AS business_type,
|
||||
sub_companies.created_datetime AS sub_company_created_datetime,
|
||||
sub_companies.updated_datetime AS sub_company_updated_datetime
|
||||
sub_companies.sub_company_id AS sub_company_id,
|
||||
sub_companies.name AS sub_company_name,
|
||||
sub_companies.sub_company_type AS business_type,
|
||||
sub_companies.created_datetime AS sub_company_created_datetime,
|
||||
sub_companies.updated_datetime AS sub_company_updated_datetime
|
||||
|
||||
FROM parent_companies
|
||||
|
||||
@@ -56,39 +60,50 @@ parent_companies_and_sub_companies_map_constants AS (
|
||||
parent_companies_join_sub_companies.autocount_id,
|
||||
parent_companies_join_sub_companies.parent_company_name,
|
||||
|
||||
COALESCE(company_types.name, parent_companies_join_sub_companies.company_type::string) AS company_type,
|
||||
COALESCE(company_types.name, parent_companies_join_sub_companies.company_type::string) AS company_type,
|
||||
|
||||
COALESCE(status.name, parent_companies_join_sub_companies.status::string) AS status,
|
||||
COALESCE(status.name, parent_companies_join_sub_companies.status::string) AS status,
|
||||
|
||||
parent_companies_join_sub_companies.parent_company_created_datetime,
|
||||
parent_companies_join_sub_companies.parent_company_updated_datetime,
|
||||
parent_companies_join_sub_companies.sub_company_id,
|
||||
parent_companies_join_sub_companies.sub_company_name,
|
||||
|
||||
COALESCE(business_type.name, parent_companies_join_sub_companies.business_type::string) AS business_type,
|
||||
COALESCE(business_type.name, parent_companies_join_sub_companies.business_type::string) AS business_type,
|
||||
|
||||
parent_companies_join_sub_companies.sub_company_created_datetime,
|
||||
parent_companies_join_sub_companies.sub_company_updated_datetime,
|
||||
|
||||
sub_company_marking_connections.sub_company_marking_id,
|
||||
sub_company_marking_connections.is_credit_term_company,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
CASE
|
||||
WHEN sub_company_marking_id IN (SELECT * FROM migrated_sub_company_marking_id)
|
||||
OR
|
||||
DATE(sub_company_marking_connections.created_datetime) = '2021-08-18'
|
||||
THEN 1
|
||||
ELSE 0
|
||||
END AS is_migrated_company,
|
||||
|
||||
'{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime
|
||||
|
||||
FROM parent_companies_join_sub_companies
|
||||
|
||||
LEFT JOIN sub_company_marking_connections
|
||||
ON (parent_companies_join_sub_companies.sub_company_id = sub_company_marking_connections.sub_company_id)
|
||||
|
||||
LEFT JOIN parent_company_types AS company_types
|
||||
LEFT JOIN parent_company_types AS company_types
|
||||
ON (parent_companies_join_sub_companies.company_type = company_types.id)
|
||||
|
||||
LEFT JOIN sub_company_types AS business_type
|
||||
LEFT JOIN sub_company_types AS business_type
|
||||
ON (parent_companies_join_sub_companies.business_type = business_type.id)
|
||||
|
||||
LEFT JOIN status
|
||||
ON (parent_companies_join_sub_companies.status = status.id)
|
||||
|
||||
),
|
||||
|
||||
|
||||
-- FINAL
|
||||
final__stg_shipping__parent_and_sub_companies AS (
|
||||
|
||||
@@ -101,6 +116,8 @@ final__stg_shipping__parent_and_sub_companies AS (
|
||||
|
||||
-- dimensions
|
||||
status,
|
||||
is_credit_term_company,
|
||||
is_migrated_company,
|
||||
parent_company_name,
|
||||
sub_company_name,
|
||||
company_type,
|
||||
@@ -118,6 +135,7 @@ final__stg_shipping__parent_and_sub_companies AS (
|
||||
_dbt_ran_datetime
|
||||
|
||||
FROM parent_companies_and_sub_companies_map_constants
|
||||
|
||||
)
|
||||
|
||||
SELECT * FROM final__stg_shipping__parent_and_sub_companies
|
||||
SELECT * FROM final__stg_shipping__parent_and_sub_companies
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user