mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-13 08:15:14 +02:00
Initial open-source release
This commit is contained in:
commit
1a42152e6f
1199 changed files with 257054 additions and 0 deletions
15
python/klo-sl/sources/b2b_saas/abm_engagements.yaml
Normal file
15
python/klo-sl/sources/b2b_saas/abm_engagements.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
name: abm_engagements
|
||||
table: abm_engagements
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: engagement_month
|
||||
type: string
|
||||
- name: row_id
|
||||
type: number
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
18
python/klo-sl/sources/b2b_saas/account_intent_signals.yaml
Normal file
18
python/klo-sl/sources/b2b_saas/account_intent_signals.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
name: account_intent_signals
|
||||
table: account_intent_signals
|
||||
grain:
|
||||
- signal_id
|
||||
columns:
|
||||
- name: signal_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: signal_date
|
||||
type: time
|
||||
role: time
|
||||
- name: topic
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
23
python/klo-sl/sources/b2b_saas/accounts.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/accounts.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: accounts
|
||||
table: accounts
|
||||
grain:
|
||||
- account_id
|
||||
columns:
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: account_name
|
||||
type: string
|
||||
- name: csm_rep_id
|
||||
type: number
|
||||
- name: industry
|
||||
type: string
|
||||
- name: is_customer
|
||||
type: string
|
||||
- name: region
|
||||
type: string
|
||||
- name: segment
|
||||
type: string
|
||||
joins:
|
||||
- to: sales_reps
|
||||
'on': csm_rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
36
python/klo-sl/sources/b2b_saas/activities.yaml
Normal file
36
python/klo-sl/sources/b2b_saas/activities.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: activities
|
||||
table: activities
|
||||
grain:
|
||||
- activity_id
|
||||
columns:
|
||||
- name: activity_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: activity_date
|
||||
type: time
|
||||
role: time
|
||||
- name: activity_type
|
||||
type: string
|
||||
- name: channel
|
||||
type: string
|
||||
- name: direction
|
||||
type: string
|
||||
- name: duration_minutes
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: subject
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
13
python/klo-sl/sources/b2b_saas/ad_accounts.yaml
Normal file
13
python/klo-sl/sources/b2b_saas/ad_accounts.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name: ad_accounts
|
||||
table: ad_accounts
|
||||
grain:
|
||||
- ad_account_id
|
||||
columns:
|
||||
- name: ad_account_id
|
||||
type: number
|
||||
- name: account_name
|
||||
type: string
|
||||
- name: currency
|
||||
type: string
|
||||
- name: platform
|
||||
type: string
|
||||
24
python/klo-sl/sources/b2b_saas/ad_ad_stats.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/ad_ad_stats.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: ad_ad_stats
|
||||
table: ad_ad_stats
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: ad_id
|
||||
type: number
|
||||
- name: clicks
|
||||
type: number
|
||||
- name: conversions
|
||||
type: number
|
||||
- name: impressions
|
||||
type: number
|
||||
- name: row_id
|
||||
type: number
|
||||
- name: spend
|
||||
type: number
|
||||
- name: stat_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: ads
|
||||
'on': ad_id = ads.ad_id
|
||||
relationship: many_to_one
|
||||
28
python/klo-sl/sources/b2b_saas/ad_campaigns.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/ad_campaigns.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: ad_campaigns
|
||||
table: ad_campaigns
|
||||
grain:
|
||||
- ad_campaign_id
|
||||
columns:
|
||||
- name: ad_campaign_id
|
||||
type: number
|
||||
- name: ad_account_id
|
||||
type: number
|
||||
- name: campaign_name
|
||||
type: string
|
||||
- name: channel
|
||||
type: string
|
||||
- name: end_date
|
||||
type: time
|
||||
role: time
|
||||
- name: objective
|
||||
type: string
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: ad_accounts
|
||||
'on': ad_account_id = ad_accounts.ad_account_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': ad_account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
24
python/klo-sl/sources/b2b_saas/ad_creative_stats.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/ad_creative_stats.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: ad_creative_stats
|
||||
table: ad_creative_stats
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: clicks
|
||||
type: number
|
||||
- name: conversions
|
||||
type: number
|
||||
- name: creative_id
|
||||
type: number
|
||||
- name: impressions
|
||||
type: number
|
||||
- name: row_id
|
||||
type: number
|
||||
- name: spend
|
||||
type: number
|
||||
- name: stat_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: ad_creatives
|
||||
'on': creative_id = ad_creatives.creative_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/ad_creatives.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/ad_creatives.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: ad_creatives
|
||||
table: ad_creatives
|
||||
grain:
|
||||
- creative_id
|
||||
columns:
|
||||
- name: creative_id
|
||||
type: number
|
||||
- name: ad_campaign_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: format
|
||||
type: string
|
||||
- name: name
|
||||
type: string
|
||||
joins:
|
||||
- to: ad_campaigns
|
||||
'on': ad_campaign_id = ad_campaigns.ad_campaign_id
|
||||
relationship: many_to_one
|
||||
17
python/klo-sl/sources/b2b_saas/ad_groups.yaml
Normal file
17
python/klo-sl/sources/b2b_saas/ad_groups.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: ad_groups
|
||||
table: ad_groups
|
||||
grain:
|
||||
- ad_group_id
|
||||
columns:
|
||||
- name: ad_group_id
|
||||
type: number
|
||||
- name: ad_campaign_id
|
||||
type: number
|
||||
- name: name
|
||||
type: string
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: ad_campaigns
|
||||
'on': ad_campaign_id = ad_campaigns.ad_campaign_id
|
||||
relationship: many_to_one
|
||||
24
python/klo-sl/sources/b2b_saas/ad_stats.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/ad_stats.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: ad_stats
|
||||
table: ad_stats
|
||||
grain:
|
||||
- stat_id
|
||||
columns:
|
||||
- name: stat_id
|
||||
type: number
|
||||
- name: ad_campaign_id
|
||||
type: number
|
||||
- name: clicks
|
||||
type: number
|
||||
- name: conversions
|
||||
type: number
|
||||
- name: impressions
|
||||
type: number
|
||||
- name: spend
|
||||
type: number
|
||||
- name: stat_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: ad_campaigns
|
||||
'on': ad_campaign_id = ad_campaigns.ad_campaign_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/ads.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/ads.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: ads
|
||||
table: ads
|
||||
grain:
|
||||
- ad_id
|
||||
columns:
|
||||
- name: ad_id
|
||||
type: number
|
||||
- name: ad_group_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: name
|
||||
type: string
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: ad_groups
|
||||
'on': ad_group_id = ad_groups.ad_group_id
|
||||
relationship: many_to_one
|
||||
23
python/klo-sl/sources/b2b_saas/ap_bills.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/ap_bills.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: ap_bills
|
||||
table: ap_bills
|
||||
grain:
|
||||
- bill_id
|
||||
columns:
|
||||
- name: bill_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: bill_date
|
||||
type: time
|
||||
role: time
|
||||
- name: due_date
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
- name: vendor_id
|
||||
type: number
|
||||
joins:
|
||||
- to: vendors
|
||||
'on': vendor_id = vendors.vendor_id
|
||||
relationship: many_to_one
|
||||
26
python/klo-sl/sources/b2b_saas/approvals.yaml
Normal file
26
python/klo-sl/sources/b2b_saas/approvals.yaml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
name: approvals
|
||||
table: approvals
|
||||
grain:
|
||||
- approval_id
|
||||
columns:
|
||||
- name: approval_id
|
||||
type: number
|
||||
- name: approved_at
|
||||
type: time
|
||||
role: time
|
||||
- name: approver_rep_id
|
||||
type: number
|
||||
- name: quote_id
|
||||
type: number
|
||||
- name: requested_at
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: sales_reps
|
||||
'on': approver_rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
- to: quotes
|
||||
'on': quote_id = quotes.quote_id
|
||||
relationship: many_to_one
|
||||
22
python/klo-sl/sources/b2b_saas/attribution_credits.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/attribution_credits.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: attribution_credits
|
||||
table: attribution_credits
|
||||
grain:
|
||||
- credit_id
|
||||
columns:
|
||||
- name: credit_id
|
||||
type: number
|
||||
- name: credit
|
||||
type: string
|
||||
- name: model
|
||||
type: string
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: touchpoint_id
|
||||
type: number
|
||||
joins:
|
||||
- to: touchpoints
|
||||
'on': touchpoint_id = touchpoints.touchpoint_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
15
python/klo-sl/sources/b2b_saas/budgets.yaml
Normal file
15
python/klo-sl/sources/b2b_saas/budgets.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
name: budgets
|
||||
table: budgets
|
||||
grain:
|
||||
- budget_id
|
||||
columns:
|
||||
- name: budget_id
|
||||
type: number
|
||||
- name: department
|
||||
type: string
|
||||
- name: period_end
|
||||
type: string
|
||||
- name: period_start
|
||||
type: string
|
||||
- name: planned_amount
|
||||
type: number
|
||||
28
python/klo-sl/sources/b2b_saas/calls.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/calls.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: calls
|
||||
table: calls
|
||||
grain:
|
||||
- call_id
|
||||
columns:
|
||||
- name: call_id
|
||||
type: number
|
||||
- name: call_date
|
||||
type: time
|
||||
role: time
|
||||
- name: duration_minutes
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: sentiment
|
||||
type: time
|
||||
role: time
|
||||
- name: transcript_url
|
||||
type: string
|
||||
joins:
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
23
python/klo-sl/sources/b2b_saas/campaign_members.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/campaign_members.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: campaign_members
|
||||
table: campaign_members
|
||||
grain:
|
||||
- campaign_member_id
|
||||
columns:
|
||||
- name: campaign_member_id
|
||||
type: number
|
||||
- name: campaign_id
|
||||
type: number
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: responded_at
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: campaigns
|
||||
'on': campaign_id = campaigns.campaign_id
|
||||
relationship: many_to_one
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
19
python/klo-sl/sources/b2b_saas/campaigns.yaml
Normal file
19
python/klo-sl/sources/b2b_saas/campaigns.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: campaigns
|
||||
table: campaigns
|
||||
grain:
|
||||
- campaign_id
|
||||
columns:
|
||||
- name: campaign_id
|
||||
type: number
|
||||
- name: budget
|
||||
type: string
|
||||
- name: campaign_name
|
||||
type: string
|
||||
- name: end_date
|
||||
type: time
|
||||
role: time
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
- name: type
|
||||
type: string
|
||||
22
python/klo-sl/sources/b2b_saas/card_transactions.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/card_transactions.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: card_transactions
|
||||
table: card_transactions
|
||||
grain:
|
||||
- amount
|
||||
columns:
|
||||
- name: amount
|
||||
type: number
|
||||
- name: card_txn_id
|
||||
type: number
|
||||
- name: department
|
||||
type: string
|
||||
- name: employee_email
|
||||
type: string
|
||||
- name: txn_date
|
||||
type: time
|
||||
role: time
|
||||
- name: vendor_id
|
||||
type: number
|
||||
joins:
|
||||
- to: vendors
|
||||
'on': vendor_id = vendors.vendor_id
|
||||
relationship: many_to_one
|
||||
12
python/klo-sl/sources/b2b_saas/cash_balances.yaml
Normal file
12
python/klo-sl/sources/b2b_saas/cash_balances.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name: cash_balances
|
||||
table: cash_balances
|
||||
grain:
|
||||
- balance
|
||||
columns:
|
||||
- name: balance
|
||||
type: string
|
||||
- name: balance_date
|
||||
type: time
|
||||
role: time
|
||||
- name: bank_account
|
||||
type: string
|
||||
24
python/klo-sl/sources/b2b_saas/charges.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/charges.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: charges
|
||||
table: charges
|
||||
grain:
|
||||
- charge_id
|
||||
columns:
|
||||
- name: charge_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: currency
|
||||
type: string
|
||||
- name: payment_intent_id
|
||||
type: number
|
||||
- name: payment_method
|
||||
type: string
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: payment_intents
|
||||
'on': payment_intent_id = payment_intents.payment_intent_id
|
||||
relationship: many_to_one
|
||||
290
python/klo-sl/sources/b2b_saas/churn_risk.yaml
Normal file
290
python/klo-sl/sources/b2b_saas/churn_risk.yaml
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
name: churn_risk
|
||||
description: |
|
||||
Per-account churn risk scoring for B2B SaaS customers. Combines signals from
|
||||
subscriptions (cancellation history), support tickets (severity, SLA breaches),
|
||||
product usage (adoption decline), contracts (renewal proximity), CSM activities
|
||||
(engagement recency), and invoices (payment issues) into a weighted composite
|
||||
risk_score (0-1) and risk_tier (High/Medium/Low). One row per customer account.
|
||||
sql: |
|
||||
WITH sub_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
MAX(CASE WHEN canceled_at IS NOT NULL THEN 1 ELSE 0 END) AS has_canceled,
|
||||
COUNT(CASE WHEN canceled_at IS NOT NULL THEN 1 END) AS canceled_count,
|
||||
STRING_AGG(DISTINCT churn_reason, ', ') AS churn_reasons
|
||||
FROM subscriptions
|
||||
GROUP BY account_id
|
||||
),
|
||||
ticket_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
COUNT(*) AS total_tickets,
|
||||
COUNT(CASE WHEN status = 'Open' THEN 1 END) AS open_tickets,
|
||||
COUNT(CASE WHEN severity = 'High' THEN 1 END) AS high_severity_tickets,
|
||||
COUNT(CASE WHEN sla_breached = '1' OR sla_breached = 'true' THEN 1 END) AS sla_breaches
|
||||
FROM support_tickets
|
||||
GROUP BY account_id
|
||||
),
|
||||
usage_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
AVG(CASE WHEN CURRENT_DATE - usage_date <= 90
|
||||
THEN CAST(active_users AS NUMERIC) END) AS recent_active_users,
|
||||
AVG(CASE WHEN CURRENT_DATE - usage_date > 90
|
||||
AND CURRENT_DATE - usage_date <= 180
|
||||
THEN CAST(active_users AS NUMERIC) END) AS prior_active_users,
|
||||
AVG(CASE WHEN CURRENT_DATE - usage_date <= 90
|
||||
THEN CAST(events_count AS NUMERIC) END) AS recent_events,
|
||||
AVG(CASE WHEN CURRENT_DATE - usage_date > 90
|
||||
AND CURRENT_DATE - usage_date <= 180
|
||||
THEN CAST(events_count AS NUMERIC) END) AS prior_events
|
||||
FROM product_usage
|
||||
GROUP BY account_id
|
||||
),
|
||||
contract_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
MAX(arr) AS current_arr,
|
||||
MIN(CASE WHEN status = 'Active'
|
||||
THEN end_date - CURRENT_DATE END) AS days_to_renewal,
|
||||
COUNT(CASE WHEN status = 'Active' THEN 1 END) AS active_contracts
|
||||
FROM contracts
|
||||
GROUP BY account_id
|
||||
),
|
||||
activity_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
COUNT(CASE WHEN CURRENT_DATE - activity_date::date <= 90
|
||||
THEN 1 END) AS recent_activities,
|
||||
MIN(CURRENT_DATE - activity_date::date) AS days_since_last_activity
|
||||
FROM activities
|
||||
GROUP BY account_id
|
||||
),
|
||||
invoice_signals AS (
|
||||
SELECT
|
||||
account_id,
|
||||
COUNT(CASE WHEN status = 'Partial' THEN 1 END) AS partial_invoices,
|
||||
COUNT(CASE WHEN CURRENT_DATE > due_date
|
||||
AND status != 'Paid' THEN 1 END) AS overdue_invoices
|
||||
FROM invoices
|
||||
GROUP BY account_id
|
||||
),
|
||||
scored AS (
|
||||
SELECT
|
||||
a.account_id,
|
||||
COALESCE(s.has_canceled, 0) AS has_canceled,
|
||||
COALESCE(s.canceled_count, 0) AS canceled_count,
|
||||
s.churn_reasons,
|
||||
COALESCE(t.open_tickets, 0) AS open_tickets,
|
||||
COALESCE(t.high_severity_tickets, 0) AS high_severity_tickets,
|
||||
COALESCE(t.sla_breaches, 0) AS sla_breaches,
|
||||
COALESCE(u.recent_active_users, 0) AS recent_active_users,
|
||||
COALESCE(u.prior_active_users, 0) AS prior_active_users,
|
||||
COALESCE(u.recent_events, 0) AS recent_events,
|
||||
COALESCE(c.current_arr, 0) AS current_arr,
|
||||
COALESCE(c.days_to_renewal, 999) AS days_to_renewal,
|
||||
COALESCE(c.active_contracts, 0) AS active_contracts,
|
||||
COALESCE(act.recent_activities, 0) AS recent_activities,
|
||||
COALESCE(act.days_since_last_activity, 999) AS days_since_last_activity,
|
||||
COALESCE(inv.partial_invoices, 0) AS partial_invoices,
|
||||
COALESCE(inv.overdue_invoices, 0) AS overdue_invoices,
|
||||
CASE WHEN COALESCE(s.has_canceled, 0) = 1 THEN 1.0
|
||||
WHEN COALESCE(s.canceled_count, 0) > 0 THEN 0.7
|
||||
ELSE 0.1 END AS subscription_risk,
|
||||
CASE WHEN COALESCE(t.high_severity_tickets, 0) >= 3 THEN 0.9
|
||||
WHEN COALESCE(t.sla_breaches, 0) >= 2 THEN 0.8
|
||||
WHEN COALESCE(t.open_tickets, 0) >= 3 THEN 0.7
|
||||
WHEN COALESCE(t.open_tickets, 0) >= 1 THEN 0.4
|
||||
ELSE 0.1 END AS support_risk,
|
||||
CASE WHEN COALESCE(u.recent_active_users, 0) = 0 THEN 0.9
|
||||
WHEN COALESCE(u.prior_active_users, 0) > 0
|
||||
AND COALESCE(u.recent_active_users, 0) < COALESCE(u.prior_active_users, 0) * 0.5
|
||||
THEN 0.8
|
||||
WHEN COALESCE(u.prior_active_users, 0) > 0
|
||||
AND COALESCE(u.recent_active_users, 0) < COALESCE(u.prior_active_users, 0) * 0.8
|
||||
THEN 0.5
|
||||
ELSE 0.1 END AS usage_risk,
|
||||
CASE WHEN COALESCE(c.days_to_renewal, 999) <= 30 THEN 0.9
|
||||
WHEN COALESCE(c.days_to_renewal, 999) <= 60 THEN 0.7
|
||||
WHEN COALESCE(c.days_to_renewal, 999) <= 90 THEN 0.5
|
||||
WHEN COALESCE(c.active_contracts, 0) = 0 THEN 0.8
|
||||
ELSE 0.1 END AS contract_risk,
|
||||
CASE WHEN COALESCE(act.days_since_last_activity, 999) > 90 THEN 0.9
|
||||
WHEN COALESCE(act.days_since_last_activity, 999) > 60 THEN 0.7
|
||||
WHEN COALESCE(act.recent_activities, 0) <= 2 THEN 0.6
|
||||
WHEN COALESCE(act.days_since_last_activity, 999) > 30 THEN 0.4
|
||||
ELSE 0.1 END AS engagement_risk,
|
||||
CASE WHEN COALESCE(inv.overdue_invoices, 0) >= 2 THEN 0.9
|
||||
WHEN COALESCE(inv.overdue_invoices, 0) >= 1 THEN 0.7
|
||||
WHEN COALESCE(inv.partial_invoices, 0) >= 2 THEN 0.6
|
||||
WHEN COALESCE(inv.partial_invoices, 0) >= 1 THEN 0.3
|
||||
ELSE 0.1 END AS payment_risk
|
||||
FROM accounts a
|
||||
LEFT JOIN sub_signals s ON a.account_id = s.account_id
|
||||
LEFT JOIN ticket_signals t ON a.account_id = t.account_id
|
||||
LEFT JOIN usage_signals u ON a.account_id = u.account_id
|
||||
LEFT JOIN contract_signals c ON a.account_id = c.account_id
|
||||
LEFT JOIN activity_signals act ON a.account_id = act.account_id
|
||||
LEFT JOIN invoice_signals inv ON a.account_id = inv.account_id
|
||||
WHERE a.is_customer = '1'
|
||||
)
|
||||
SELECT
|
||||
account_id,
|
||||
has_canceled,
|
||||
canceled_count,
|
||||
churn_reasons,
|
||||
open_tickets,
|
||||
high_severity_tickets,
|
||||
sla_breaches,
|
||||
recent_active_users,
|
||||
prior_active_users,
|
||||
recent_events,
|
||||
current_arr,
|
||||
days_to_renewal,
|
||||
active_contracts,
|
||||
recent_activities,
|
||||
days_since_last_activity,
|
||||
partial_invoices,
|
||||
overdue_invoices,
|
||||
subscription_risk,
|
||||
support_risk,
|
||||
usage_risk,
|
||||
contract_risk,
|
||||
engagement_risk,
|
||||
payment_risk,
|
||||
ROUND(
|
||||
subscription_risk * 0.20
|
||||
+ support_risk * 0.20
|
||||
+ usage_risk * 0.20
|
||||
+ contract_risk * 0.15
|
||||
+ engagement_risk * 0.15
|
||||
+ payment_risk * 0.10,
|
||||
3
|
||||
) AS risk_score,
|
||||
CASE
|
||||
WHEN (subscription_risk * 0.20
|
||||
+ support_risk * 0.20
|
||||
+ usage_risk * 0.20
|
||||
+ contract_risk * 0.15
|
||||
+ engagement_risk * 0.15
|
||||
+ payment_risk * 0.10) >= 0.7 THEN 'High'
|
||||
WHEN (subscription_risk * 0.20
|
||||
+ support_risk * 0.20
|
||||
+ usage_risk * 0.20
|
||||
+ contract_risk * 0.15
|
||||
+ engagement_risk * 0.15
|
||||
+ payment_risk * 0.10) >= 0.4 THEN 'Medium'
|
||||
ELSE 'Low'
|
||||
END AS risk_tier
|
||||
FROM scored
|
||||
grain:
|
||||
- account_id
|
||||
columns:
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: has_canceled
|
||||
type: number
|
||||
description: "1 if the account has any canceled subscription"
|
||||
- name: canceled_count
|
||||
type: number
|
||||
description: "Number of canceled subscriptions"
|
||||
- name: churn_reasons
|
||||
type: string
|
||||
description: "Comma-separated distinct churn reasons from subscriptions"
|
||||
- name: open_tickets
|
||||
type: number
|
||||
description: "Count of currently open support tickets"
|
||||
- name: high_severity_tickets
|
||||
type: number
|
||||
description: "Count of high-severity support tickets"
|
||||
- name: sla_breaches
|
||||
type: number
|
||||
description: "Count of support tickets with SLA breaches"
|
||||
- name: recent_active_users
|
||||
type: number
|
||||
description: "Average active users in the last 90 days"
|
||||
- name: prior_active_users
|
||||
type: number
|
||||
description: "Average active users 90-180 days ago (for trend comparison)"
|
||||
- name: recent_events
|
||||
type: number
|
||||
description: "Average event count in the last 90 days"
|
||||
- name: current_arr
|
||||
type: number
|
||||
description: "Highest ARR from active contracts"
|
||||
- name: days_to_renewal
|
||||
type: number
|
||||
description: "Days until the nearest active contract expires"
|
||||
- name: active_contracts
|
||||
type: number
|
||||
description: "Count of active contracts"
|
||||
- name: recent_activities
|
||||
type: number
|
||||
description: "CSM activities (calls, meetings, emails, tasks) in the last 90 days"
|
||||
- name: days_since_last_activity
|
||||
type: number
|
||||
description: "Days since the most recent CSM activity"
|
||||
- name: partial_invoices
|
||||
type: number
|
||||
description: "Count of invoices with Partial payment status"
|
||||
- name: overdue_invoices
|
||||
type: number
|
||||
description: "Count of overdue unpaid invoices"
|
||||
- name: subscription_risk
|
||||
type: number
|
||||
description: "Subscription cancellation risk sub-score (0.0-1.0)"
|
||||
- name: support_risk
|
||||
type: number
|
||||
description: "Support burden risk sub-score (0.0-1.0)"
|
||||
- name: usage_risk
|
||||
type: number
|
||||
description: "Product usage decline risk sub-score (0.0-1.0)"
|
||||
- name: contract_risk
|
||||
type: number
|
||||
description: "Contract renewal proximity risk sub-score (0.0-1.0)"
|
||||
- name: engagement_risk
|
||||
type: number
|
||||
description: "CSM engagement gap risk sub-score (0.0-1.0)"
|
||||
- name: payment_risk
|
||||
type: number
|
||||
description: "Payment issues risk sub-score (0.0-1.0)"
|
||||
- name: risk_score
|
||||
type: number
|
||||
description: "Weighted composite churn risk score (0.0-1.0); higher = riskier"
|
||||
- name: risk_tier
|
||||
type: string
|
||||
description: "Churn risk tier: High (>=0.7), Medium (>=0.4), Low (<0.4)"
|
||||
joins:
|
||||
- to: accounts
|
||||
"on": account_id = accounts.account_id
|
||||
relationship: one_to_one
|
||||
measures:
|
||||
- name: avg_risk_score
|
||||
expr: avg(risk_score)
|
||||
description: "Average churn risk score across accounts"
|
||||
- name: high_risk_accounts
|
||||
expr: count(account_id)
|
||||
filter: "risk_tier = 'High'"
|
||||
description: "Number of accounts in the High risk tier"
|
||||
- name: medium_risk_accounts
|
||||
expr: count(account_id)
|
||||
filter: "risk_tier = 'Medium'"
|
||||
description: "Number of accounts in the Medium risk tier"
|
||||
- name: low_risk_accounts
|
||||
expr: count(account_id)
|
||||
filter: "risk_tier = 'Low'"
|
||||
description: "Number of accounts in the Low risk tier"
|
||||
- name: total_arr_at_risk
|
||||
expr: sum(current_arr)
|
||||
filter: "risk_tier = 'High'"
|
||||
description: "Total ARR from accounts in the High risk tier"
|
||||
- name: avg_support_risk
|
||||
expr: avg(support_risk)
|
||||
description: "Average support burden risk sub-score"
|
||||
- name: avg_usage_risk
|
||||
expr: avg(usage_risk)
|
||||
description: "Average usage decline risk sub-score"
|
||||
- name: accounts_expiring_90d
|
||||
expr: count(account_id)
|
||||
filter: "days_to_renewal <= 90"
|
||||
description: "Accounts with contracts expiring within 90 days"
|
||||
23
python/klo-sl/sources/b2b_saas/contacts.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/contacts.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: contacts
|
||||
table: contacts
|
||||
grain:
|
||||
- contact_id
|
||||
columns:
|
||||
- name: contact_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: email
|
||||
type: string
|
||||
- name: first_name
|
||||
type: string
|
||||
- name: last_name
|
||||
type: string
|
||||
- name: phone
|
||||
type: string
|
||||
- name: title
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
16
python/klo-sl/sources/b2b_saas/content_assets.yaml
Normal file
16
python/klo-sl/sources/b2b_saas/content_assets.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
name: content_assets
|
||||
table: content_assets
|
||||
grain:
|
||||
- asset_id
|
||||
columns:
|
||||
- name: asset_id
|
||||
type: number
|
||||
- name: content_type
|
||||
type: string
|
||||
- name: publish_date
|
||||
type: time
|
||||
role: time
|
||||
- name: title
|
||||
type: string
|
||||
- name: url
|
||||
type: string
|
||||
33
python/klo-sl/sources/b2b_saas/content_touches.yaml
Normal file
33
python/klo-sl/sources/b2b_saas/content_touches.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: content_touches
|
||||
table: content_touches
|
||||
grain:
|
||||
- touch_id
|
||||
columns:
|
||||
- name: touch_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: action
|
||||
type: string
|
||||
- name: asset_id
|
||||
type: number
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: touched_at
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: content_assets
|
||||
'on': asset_id = content_assets.asset_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
30
python/klo-sl/sources/b2b_saas/contracts.yaml
Normal file
30
python/klo-sl/sources/b2b_saas/contracts.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
name: contracts
|
||||
table: contracts
|
||||
grain:
|
||||
- contract_id
|
||||
columns:
|
||||
- name: contract_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: arr
|
||||
type: number
|
||||
- name: contract_number
|
||||
type: string
|
||||
- name: end_date
|
||||
type: time
|
||||
role: time
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
23
python/klo-sl/sources/b2b_saas/crm_notes.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/crm_notes.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: crm_notes
|
||||
table: crm_notes
|
||||
grain:
|
||||
- note_id
|
||||
columns:
|
||||
- name: note_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: note_text
|
||||
type: string
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
joins:
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
9
python/klo-sl/sources/b2b_saas/currencies.yaml
Normal file
9
python/klo-sl/sources/b2b_saas/currencies.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
name: currencies
|
||||
table: currencies
|
||||
grain:
|
||||
- currency_code
|
||||
columns:
|
||||
- name: currency_code
|
||||
type: string
|
||||
- name: currency_name
|
||||
type: string
|
||||
9
python/klo-sl/sources/b2b_saas/departments_hr.yaml
Normal file
9
python/klo-sl/sources/b2b_saas/departments_hr.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
name: departments_hr
|
||||
table: departments_hr
|
||||
grain:
|
||||
- dept_id
|
||||
columns:
|
||||
- name: dept_id
|
||||
type: number
|
||||
- name: dept_name
|
||||
type: string
|
||||
23
python/klo-sl/sources/b2b_saas/disputes.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/disputes.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: disputes
|
||||
table: disputes
|
||||
grain:
|
||||
- dispute_id
|
||||
columns:
|
||||
- name: dispute_id
|
||||
type: number
|
||||
- name: charge_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: reason
|
||||
type: string
|
||||
- name: resolved_at
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: charges
|
||||
'on': charge_id = charges.charge_id
|
||||
relationship: many_to_one
|
||||
18
python/klo-sl/sources/b2b_saas/email_events.yaml
Normal file
18
python/klo-sl/sources/b2b_saas/email_events.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
name: email_events
|
||||
table: email_events
|
||||
grain:
|
||||
- event_id
|
||||
columns:
|
||||
- name: event_id
|
||||
type: number
|
||||
- name: event_at
|
||||
type: time
|
||||
role: time
|
||||
- name: event_type
|
||||
type: string
|
||||
- name: send_id
|
||||
type: number
|
||||
joins:
|
||||
- to: email_sends
|
||||
'on': send_id = email_sends.send_id
|
||||
relationship: many_to_one
|
||||
33
python/klo-sl/sources/b2b_saas/email_sends.yaml
Normal file
33
python/klo-sl/sources/b2b_saas/email_sends.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: email_sends
|
||||
table: email_sends
|
||||
grain:
|
||||
- send_id
|
||||
columns:
|
||||
- name: send_id
|
||||
type: number
|
||||
- name: campaign_id
|
||||
type: number
|
||||
- name: email_id
|
||||
type: number
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: sent_at
|
||||
type: time
|
||||
role: time
|
||||
- name: sequence_id
|
||||
type: number
|
||||
joins:
|
||||
- to: campaigns
|
||||
'on': campaign_id = campaigns.campaign_id
|
||||
relationship: many_to_one
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: sequences
|
||||
'on': sequence_id = sequences.sequence_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
33
python/klo-sl/sources/b2b_saas/employees.yaml
Normal file
33
python/klo-sl/sources/b2b_saas/employees.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: employees
|
||||
table: employees
|
||||
grain:
|
||||
- employee_id
|
||||
columns:
|
||||
- name: employee_id
|
||||
type: number
|
||||
- name: base_salary
|
||||
type: number
|
||||
- name: benefits_cost
|
||||
type: number
|
||||
- name: dept_id
|
||||
type: number
|
||||
- name: email
|
||||
type: string
|
||||
- name: first_name
|
||||
type: string
|
||||
- name: hire_date
|
||||
type: time
|
||||
role: time
|
||||
- name: last_name
|
||||
type: string
|
||||
- name: region
|
||||
type: string
|
||||
- name: role
|
||||
type: string
|
||||
- name: termination_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: departments_hr
|
||||
'on': dept_id = departments_hr.dept_id
|
||||
relationship: many_to_one
|
||||
21
python/klo-sl/sources/b2b_saas/etl_runs.yaml
Normal file
21
python/klo-sl/sources/b2b_saas/etl_runs.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: etl_runs
|
||||
table: etl_runs
|
||||
grain:
|
||||
- run_id
|
||||
columns:
|
||||
- name: run_id
|
||||
type: number
|
||||
- name: destination
|
||||
type: string
|
||||
- name: ended_at
|
||||
type: time
|
||||
role: time
|
||||
- name: rows_processed
|
||||
type: number
|
||||
- name: source
|
||||
type: string
|
||||
- name: started_at
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
17
python/klo-sl/sources/b2b_saas/fiscal_calendar.yaml
Normal file
17
python/klo-sl/sources/b2b_saas/fiscal_calendar.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: fiscal_calendar
|
||||
table: fiscal_calendar
|
||||
grain:
|
||||
- calendar_date
|
||||
columns:
|
||||
- name: calendar_date
|
||||
type: time
|
||||
- name: fiscal_month
|
||||
type: string
|
||||
- name: fiscal_quarter
|
||||
type: string
|
||||
- name: fiscal_year
|
||||
type: string
|
||||
- name: is_month_start
|
||||
type: string
|
||||
- name: is_quarter_start
|
||||
type: string
|
||||
23
python/klo-sl/sources/b2b_saas/forecast_snapshots.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/forecast_snapshots.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: forecast_snapshots
|
||||
table: forecast_snapshots
|
||||
grain:
|
||||
- snapshot_id
|
||||
columns:
|
||||
- name: snapshot_id
|
||||
type: number
|
||||
- name: category
|
||||
type: string
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: snapshot_date
|
||||
type: time
|
||||
role: time
|
||||
- name: team_id
|
||||
type: number
|
||||
joins:
|
||||
- to: sales_teams
|
||||
'on': team_id = sales_teams.team_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
14
python/klo-sl/sources/b2b_saas/fx_rates.yaml
Normal file
14
python/klo-sl/sources/b2b_saas/fx_rates.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name: fx_rates
|
||||
table: fx_rates
|
||||
grain:
|
||||
- from_currency
|
||||
columns:
|
||||
- name: from_currency
|
||||
type: string
|
||||
- name: rate
|
||||
type: string
|
||||
- name: rate_date
|
||||
type: time
|
||||
role: time
|
||||
- name: to_currency
|
||||
type: string
|
||||
23
python/klo-sl/sources/b2b_saas/ga4_event_params.yaml
Normal file
23
python/klo-sl/sources/b2b_saas/ga4_event_params.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: ga4_event_params
|
||||
table: ga4_event_params
|
||||
grain:
|
||||
- param_id
|
||||
columns:
|
||||
- name: param_id
|
||||
type: number
|
||||
- name: ga4_event_id
|
||||
type: number
|
||||
- name: key
|
||||
type: string
|
||||
- name: value
|
||||
type: string
|
||||
joins:
|
||||
- to: ga4_events
|
||||
'on': ga4_event_id = ga4_events.ga4_event_id
|
||||
relationship: many_to_one
|
||||
- to: email_events
|
||||
'on': ga4_event_id = email_events.event_id
|
||||
relationship: many_to_one
|
||||
- to: web_events
|
||||
'on': ga4_event_id = web_events.event_id
|
||||
relationship: many_to_one
|
||||
25
python/klo-sl/sources/b2b_saas/ga4_events.yaml
Normal file
25
python/klo-sl/sources/b2b_saas/ga4_events.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: ga4_events
|
||||
table: ga4_events
|
||||
grain:
|
||||
- ga4_event_id
|
||||
columns:
|
||||
- name: ga4_event_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: event_name
|
||||
type: string
|
||||
- name: event_time
|
||||
type: time
|
||||
role: time
|
||||
- name: session_id
|
||||
type: number
|
||||
- name: user_id
|
||||
type: number
|
||||
joins:
|
||||
- to: web_sessions
|
||||
'on': session_id = web_sessions.session_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
13
python/klo-sl/sources/b2b_saas/gl_accounts.yaml
Normal file
13
python/klo-sl/sources/b2b_saas/gl_accounts.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name: gl_accounts
|
||||
table: gl_accounts
|
||||
grain:
|
||||
- gl_account_id
|
||||
columns:
|
||||
- name: gl_account_id
|
||||
type: number
|
||||
- name: account_code
|
||||
type: string
|
||||
- name: name
|
||||
type: string
|
||||
- name: type
|
||||
type: string
|
||||
22
python/klo-sl/sources/b2b_saas/identities.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/identities.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: identities
|
||||
table: identities
|
||||
grain:
|
||||
- identity_id
|
||||
columns:
|
||||
- name: identity_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: device_id
|
||||
type: number
|
||||
- name: email
|
||||
type: string
|
||||
- name: user_id
|
||||
type: number
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
25
python/klo-sl/sources/b2b_saas/identity_links.yaml
Normal file
25
python/klo-sl/sources/b2b_saas/identity_links.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: identity_links
|
||||
table: identity_links
|
||||
grain:
|
||||
- link_id
|
||||
columns:
|
||||
- name: link_id
|
||||
type: number
|
||||
- name: child_identity_id
|
||||
type: number
|
||||
- name: linked_at
|
||||
type: time
|
||||
role: time
|
||||
- name: link_source
|
||||
type: string
|
||||
- name: parent_identity_id
|
||||
type: number
|
||||
joins:
|
||||
- to: identities
|
||||
'on': child_identity_id = identities.identity_id
|
||||
relationship: many_to_one
|
||||
alias: identities_1
|
||||
- to: identities
|
||||
'on': parent_identity_id = identities.identity_id
|
||||
relationship: many_to_one
|
||||
alias: identities_2
|
||||
24
python/klo-sl/sources/b2b_saas/invoice_lines.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/invoice_lines.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: invoice_lines
|
||||
table: invoice_lines
|
||||
grain:
|
||||
- invoice_line_id
|
||||
columns:
|
||||
- name: invoice_line_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: invoice_id
|
||||
type: number
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: quantity
|
||||
type: string
|
||||
- name: unit_price
|
||||
type: number
|
||||
joins:
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
- to: invoices
|
||||
'on': invoice_id = invoices.invoice_id
|
||||
relationship: many_to_one
|
||||
28
python/klo-sl/sources/b2b_saas/invoices.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/invoices.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: invoices
|
||||
table: invoices
|
||||
grain:
|
||||
- invoice_id
|
||||
columns:
|
||||
- name: invoice_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: contract_id
|
||||
type: number
|
||||
- name: currency
|
||||
type: string
|
||||
- name: due_date
|
||||
type: time
|
||||
role: time
|
||||
- name: invoice_date
|
||||
type: time
|
||||
role: time
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: contracts
|
||||
'on': contract_id = contracts.contract_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
12
python/klo-sl/sources/b2b_saas/journal_entries.yaml
Normal file
12
python/klo-sl/sources/b2b_saas/journal_entries.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name: journal_entries
|
||||
table: journal_entries
|
||||
grain:
|
||||
- journal_entry_id
|
||||
columns:
|
||||
- name: journal_entry_id
|
||||
type: number
|
||||
- name: entry_date
|
||||
type: time
|
||||
role: time
|
||||
- name: memo
|
||||
type: string
|
||||
25
python/klo-sl/sources/b2b_saas/journal_lines.yaml
Normal file
25
python/klo-sl/sources/b2b_saas/journal_lines.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: journal_lines
|
||||
table: journal_lines
|
||||
grain:
|
||||
- journal_line_id
|
||||
columns:
|
||||
- name: journal_line_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: dr_cr
|
||||
type: string
|
||||
- name: gl_account_id
|
||||
type: number
|
||||
- name: journal_entry_id
|
||||
type: number
|
||||
joins:
|
||||
- to: gl_accounts
|
||||
'on': gl_account_id = gl_accounts.gl_account_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': gl_account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: journal_entries
|
||||
'on': journal_entry_id = journal_entries.journal_entry_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/keyword_rankings.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/keyword_rankings.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: keyword_rankings
|
||||
table: keyword_rankings
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: domain
|
||||
type: string
|
||||
- name: is_competitor
|
||||
type: string
|
||||
- name: keyword
|
||||
type: string
|
||||
- name: rank
|
||||
type: string
|
||||
- name: row_id
|
||||
type: number
|
||||
- name: search_volume
|
||||
type: string
|
||||
- name: stat_date
|
||||
type: time
|
||||
role: time
|
||||
18
python/klo-sl/sources/b2b_saas/lead_status_history.yaml
Normal file
18
python/klo-sl/sources/b2b_saas/lead_status_history.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
name: lead_status_history
|
||||
table: lead_status_history
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: changed_at
|
||||
type: time
|
||||
role: time
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: row_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
43
python/klo-sl/sources/b2b_saas/leads.yaml
Normal file
43
python/klo-sl/sources/b2b_saas/leads.yaml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: leads
|
||||
table: leads
|
||||
grain:
|
||||
- lead_id
|
||||
columns:
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: converted_at
|
||||
type: time
|
||||
role: time
|
||||
- name: converted_opportunity_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: first_touch_at
|
||||
type: time
|
||||
role: time
|
||||
- name: last_touch_at
|
||||
type: time
|
||||
role: time
|
||||
- name: owner_rep_id
|
||||
type: number
|
||||
- name: source
|
||||
type: string
|
||||
- name: utm_campaign
|
||||
type: string
|
||||
- name: utm_medium
|
||||
type: string
|
||||
- name: utm_source
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': owner_rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': converted_opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
22
python/klo-sl/sources/b2b_saas/meeting_bookings.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/meeting_bookings.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: meeting_bookings
|
||||
table: meeting_bookings
|
||||
grain:
|
||||
- meeting_date
|
||||
columns:
|
||||
- name: meeting_date
|
||||
type: time
|
||||
- name: meeting_id
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: source
|
||||
type: string
|
||||
joins:
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
22
python/klo-sl/sources/b2b_saas/open_roles.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/open_roles.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: open_roles
|
||||
table: open_roles
|
||||
grain:
|
||||
- budgeted_salary
|
||||
columns:
|
||||
- name: budgeted_salary
|
||||
type: number
|
||||
- name: dept_id
|
||||
type: number
|
||||
- name: opened_date
|
||||
type: time
|
||||
role: time
|
||||
- name: req_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
- name: title
|
||||
type: string
|
||||
joins:
|
||||
- to: departments_hr
|
||||
'on': dept_id = departments_hr.dept_id
|
||||
relationship: many_to_one
|
||||
40
python/klo-sl/sources/b2b_saas/opportunities.yaml
Normal file
40
python/klo-sl/sources/b2b_saas/opportunities.yaml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
name: opportunities
|
||||
table: opportunities
|
||||
grain:
|
||||
- opportunity_id
|
||||
columns:
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: close_date
|
||||
type: time
|
||||
role: time
|
||||
- name: created_date
|
||||
type: time
|
||||
role: time
|
||||
- name: currency
|
||||
type: string
|
||||
- name: lead_source
|
||||
type: string
|
||||
- name: owner_rep_id
|
||||
type: number
|
||||
- name: parent_opportunity_id
|
||||
type: number
|
||||
- name: primary_competitor
|
||||
type: string
|
||||
- name: region
|
||||
type: string
|
||||
- name: risk_reason
|
||||
type: string
|
||||
- name: stage
|
||||
type: string
|
||||
- name: type
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': owner_rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
name: opportunity_contact_roles
|
||||
table: opportunity_contact_roles
|
||||
grain:
|
||||
- contact_id
|
||||
columns:
|
||||
- name: contact_id
|
||||
type: number
|
||||
- name: ocr_id
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: role
|
||||
type: string
|
||||
joins:
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: contacts
|
||||
'on': contact_id = contacts.contact_id
|
||||
relationship: many_to_one
|
||||
24
python/klo-sl/sources/b2b_saas/opportunity_line_items.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/opportunity_line_items.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: opportunity_line_items
|
||||
table: opportunity_line_items
|
||||
grain:
|
||||
- discount_pct
|
||||
columns:
|
||||
- name: discount_pct
|
||||
type: string
|
||||
- name: line_item_id
|
||||
type: number
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: quantity
|
||||
type: string
|
||||
- name: unit_price
|
||||
type: number
|
||||
joins:
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
name: opportunity_stage_history
|
||||
table: opportunity_stage_history
|
||||
grain:
|
||||
- history_id
|
||||
columns:
|
||||
- name: history_id
|
||||
type: number
|
||||
- name: entered_at
|
||||
type: time
|
||||
role: time
|
||||
- name: exited_at
|
||||
type: time
|
||||
role: time
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: stage
|
||||
type: string
|
||||
joins:
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
22
python/klo-sl/sources/b2b_saas/payment_intents.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/payment_intents.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: payment_intents
|
||||
table: payment_intents
|
||||
grain:
|
||||
- payment_intent_id
|
||||
columns:
|
||||
- name: payment_intent_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: currency
|
||||
type: string
|
||||
- name: invoice_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: invoices
|
||||
'on': invoice_id = invoices.invoice_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/payments.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/payments.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: payments
|
||||
table: payments
|
||||
grain:
|
||||
- payment_id
|
||||
columns:
|
||||
- name: payment_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: invoice_id
|
||||
type: number
|
||||
- name: method
|
||||
type: string
|
||||
- name: payment_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: invoices
|
||||
'on': invoice_id = invoices.invoice_id
|
||||
relationship: many_to_one
|
||||
17
python/klo-sl/sources/b2b_saas/payroll_runs.yaml
Normal file
17
python/klo-sl/sources/b2b_saas/payroll_runs.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: payroll_runs
|
||||
table: payroll_runs
|
||||
grain:
|
||||
- run_id
|
||||
columns:
|
||||
- name: run_id
|
||||
type: number
|
||||
- name: benefits
|
||||
type: number
|
||||
- name: gross_pay
|
||||
type: string
|
||||
- name: pay_period_end
|
||||
type: string
|
||||
- name: pay_period_start
|
||||
type: string
|
||||
- name: taxes
|
||||
type: string
|
||||
20
python/klo-sl/sources/b2b_saas/pricebook_entries.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/pricebook_entries.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: pricebook_entries
|
||||
table: pricebook_entries
|
||||
grain:
|
||||
- pricebook_entry_id
|
||||
columns:
|
||||
- name: pricebook_entry_id
|
||||
type: number
|
||||
- name: list_price
|
||||
type: number
|
||||
- name: pricebook_id
|
||||
type: number
|
||||
- name: product_id
|
||||
type: number
|
||||
joins:
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
- to: pricebooks
|
||||
'on': pricebook_id = pricebooks.pricebook_id
|
||||
relationship: many_to_one
|
||||
13
python/klo-sl/sources/b2b_saas/pricebooks.yaml
Normal file
13
python/klo-sl/sources/b2b_saas/pricebooks.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name: pricebooks
|
||||
table: pricebooks
|
||||
grain:
|
||||
- pricebook_id
|
||||
columns:
|
||||
- name: pricebook_id
|
||||
type: number
|
||||
- name: currency
|
||||
type: string
|
||||
- name: name
|
||||
type: string
|
||||
- name: region
|
||||
type: string
|
||||
15
python/klo-sl/sources/b2b_saas/product_costs.yaml
Normal file
15
python/klo-sl/sources/b2b_saas/product_costs.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
name: product_costs
|
||||
table: product_costs
|
||||
grain:
|
||||
- cogs_per_unit
|
||||
columns:
|
||||
- name: cogs_per_unit
|
||||
type: number
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: region
|
||||
type: string
|
||||
joins:
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/product_usage.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/product_usage.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: product_usage
|
||||
table: product_usage
|
||||
grain:
|
||||
- usage_id
|
||||
columns:
|
||||
- name: usage_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: active_users
|
||||
type: string
|
||||
- name: events_count
|
||||
type: string
|
||||
- name: usage_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
13
python/klo-sl/sources/b2b_saas/products.yaml
Normal file
13
python/klo-sl/sources/b2b_saas/products.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
name: products
|
||||
table: products
|
||||
grain:
|
||||
- product_id
|
||||
columns:
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: list_price
|
||||
type: number
|
||||
- name: product_name
|
||||
type: string
|
||||
- name: sku
|
||||
type: string
|
||||
19
python/klo-sl/sources/b2b_saas/quotas.yaml
Normal file
19
python/klo-sl/sources/b2b_saas/quotas.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: quotas
|
||||
table: quotas
|
||||
grain:
|
||||
- quota_id
|
||||
columns:
|
||||
- name: quota_id
|
||||
type: number
|
||||
- name: period_end
|
||||
type: string
|
||||
- name: period_start
|
||||
type: string
|
||||
- name: quota_arr
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
joins:
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
24
python/klo-sl/sources/b2b_saas/quote_line_items.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/quote_line_items.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: quote_line_items
|
||||
table: quote_line_items
|
||||
grain:
|
||||
- quote_line_item_id
|
||||
columns:
|
||||
- name: quote_line_item_id
|
||||
type: number
|
||||
- name: discount_pct
|
||||
type: string
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: quantity
|
||||
type: string
|
||||
- name: quote_id
|
||||
type: number
|
||||
- name: unit_price
|
||||
type: number
|
||||
joins:
|
||||
- to: quotes
|
||||
'on': quote_id = quotes.quote_id
|
||||
relationship: many_to_one
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
28
python/klo-sl/sources/b2b_saas/quotes.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/quotes.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: quotes
|
||||
table: quotes
|
||||
grain:
|
||||
- quote_id
|
||||
columns:
|
||||
- name: quote_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: pricebook_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
- to: pricebooks
|
||||
'on': pricebook_id = pricebooks.pricebook_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
20
python/klo-sl/sources/b2b_saas/refunds.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/refunds.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: refunds
|
||||
table: refunds
|
||||
grain:
|
||||
- refund_id
|
||||
columns:
|
||||
- name: refund_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: charge_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: reason
|
||||
type: string
|
||||
joins:
|
||||
- to: charges
|
||||
'on': charge_id = charges.charge_id
|
||||
relationship: many_to_one
|
||||
28
python/klo-sl/sources/b2b_saas/revenue_schedules.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/revenue_schedules.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: revenue_schedules
|
||||
table: revenue_schedules
|
||||
grain:
|
||||
- schedule_id
|
||||
columns:
|
||||
- name: schedule_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: contract_id
|
||||
type: number
|
||||
- name: end_date
|
||||
type: time
|
||||
role: time
|
||||
- name: recognition_rule
|
||||
type: string
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
- to: contracts
|
||||
'on': contract_id = contracts.contract_id
|
||||
relationship: many_to_one
|
||||
16
python/klo-sl/sources/b2b_saas/reverse_etl_jobs.yaml
Normal file
16
python/klo-sl/sources/b2b_saas/reverse_etl_jobs.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
name: reverse_etl_jobs
|
||||
table: reverse_etl_jobs
|
||||
grain:
|
||||
- job_id
|
||||
columns:
|
||||
- name: job_id
|
||||
type: number
|
||||
- name: last_run_at
|
||||
type: time
|
||||
role: time
|
||||
- name: last_status
|
||||
type: string
|
||||
- name: name
|
||||
type: string
|
||||
- name: target_system
|
||||
type: string
|
||||
27
python/klo-sl/sources/b2b_saas/sales_reps.yaml
Normal file
27
python/klo-sl/sources/b2b_saas/sales_reps.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: sales_reps
|
||||
table: sales_reps
|
||||
grain:
|
||||
- rep_id
|
||||
columns:
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: email
|
||||
type: string
|
||||
- name: first_name
|
||||
type: string
|
||||
- name: last_name
|
||||
type: string
|
||||
- name: manager_rep_id
|
||||
type: number
|
||||
- name: region
|
||||
type: string
|
||||
- name: role
|
||||
type: string
|
||||
- name: segment_focus
|
||||
type: string
|
||||
- name: team_id
|
||||
type: number
|
||||
joins:
|
||||
- to: sales_teams
|
||||
'on': team_id = sales_teams.team_id
|
||||
relationship: many_to_one
|
||||
11
python/klo-sl/sources/b2b_saas/sales_teams.yaml
Normal file
11
python/klo-sl/sources/b2b_saas/sales_teams.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
name: sales_teams
|
||||
table: sales_teams
|
||||
grain:
|
||||
- team_id
|
||||
columns:
|
||||
- name: team_id
|
||||
type: number
|
||||
- name: region
|
||||
type: string
|
||||
- name: team_name
|
||||
type: string
|
||||
20
python/klo-sl/sources/b2b_saas/search_console_stats.yaml
Normal file
20
python/klo-sl/sources/b2b_saas/search_console_stats.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
name: search_console_stats
|
||||
table: search_console_stats
|
||||
grain:
|
||||
- row_id
|
||||
columns:
|
||||
- name: clicks
|
||||
type: number
|
||||
- name: impressions
|
||||
type: number
|
||||
- name: page
|
||||
type: string
|
||||
- name: position
|
||||
type: number
|
||||
- name: query
|
||||
type: string
|
||||
- name: row_id
|
||||
type: number
|
||||
- name: stat_date
|
||||
type: time
|
||||
role: time
|
||||
28
python/klo-sl/sources/b2b_saas/sequence_enrollments.yaml
Normal file
28
python/klo-sl/sources/b2b_saas/sequence_enrollments.yaml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
name: sequence_enrollments
|
||||
table: sequence_enrollments
|
||||
grain:
|
||||
- enrollment_id
|
||||
columns:
|
||||
- name: enrollment_id
|
||||
type: number
|
||||
- name: enrolled_at
|
||||
type: time
|
||||
role: time
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: sequence_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: sequences
|
||||
'on': sequence_id = sequences.sequence_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
21
python/klo-sl/sources/b2b_saas/sequence_steps.yaml
Normal file
21
python/klo-sl/sources/b2b_saas/sequence_steps.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: sequence_steps
|
||||
table: sequence_steps
|
||||
grain:
|
||||
- step_id
|
||||
columns:
|
||||
- name: step_id
|
||||
type: number
|
||||
- name: content
|
||||
type: string
|
||||
- name: offset_days
|
||||
type: string
|
||||
- name: sequence_id
|
||||
type: number
|
||||
- name: step_order
|
||||
type: string
|
||||
- name: step_type
|
||||
type: string
|
||||
joins:
|
||||
- to: sequences
|
||||
'on': sequence_id = sequences.sequence_id
|
||||
relationship: many_to_one
|
||||
25
python/klo-sl/sources/b2b_saas/sequence_touches.yaml
Normal file
25
python/klo-sl/sources/b2b_saas/sequence_touches.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: sequence_touches
|
||||
table: sequence_touches
|
||||
grain:
|
||||
- touch_id
|
||||
columns:
|
||||
- name: touch_id
|
||||
type: number
|
||||
- name: enrollment_id
|
||||
type: number
|
||||
- name: rep_id
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
- name: touch_date
|
||||
type: time
|
||||
role: time
|
||||
- name: touch_type
|
||||
type: string
|
||||
joins:
|
||||
- to: sequence_enrollments
|
||||
'on': enrollment_id = sequence_enrollments.enrollment_id
|
||||
relationship: many_to_one
|
||||
- to: sales_reps
|
||||
'on': rep_id = sales_reps.rep_id
|
||||
relationship: many_to_one
|
||||
14
python/klo-sl/sources/b2b_saas/sequences.yaml
Normal file
14
python/klo-sl/sources/b2b_saas/sequences.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name: sequences
|
||||
table: sequences
|
||||
grain:
|
||||
- sequence_id
|
||||
columns:
|
||||
- name: sequence_id
|
||||
type: number
|
||||
- name: channel
|
||||
type: string
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: name
|
||||
type: string
|
||||
9
python/klo-sl/sources/b2b_saas/stage_weights.yaml
Normal file
9
python/klo-sl/sources/b2b_saas/stage_weights.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
name: stage_weights
|
||||
table: stage_weights
|
||||
grain:
|
||||
- stage
|
||||
columns:
|
||||
- name: stage
|
||||
type: string
|
||||
- name: weight
|
||||
type: string
|
||||
18
python/klo-sl/sources/b2b_saas/subscription_items.yaml
Normal file
18
python/klo-sl/sources/b2b_saas/subscription_items.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
name: subscription_items
|
||||
table: subscription_items
|
||||
grain:
|
||||
- product_id
|
||||
columns:
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: sub_item_id
|
||||
type: number
|
||||
- name: subscription_id
|
||||
type: number
|
||||
joins:
|
||||
- to: products
|
||||
'on': product_id = products.product_id
|
||||
relationship: many_to_one
|
||||
- to: subscriptions
|
||||
'on': subscription_id = subscriptions.subscription_id
|
||||
relationship: many_to_one
|
||||
24
python/klo-sl/sources/b2b_saas/subscriptions.yaml
Normal file
24
python/klo-sl/sources/b2b_saas/subscriptions.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
name: subscriptions
|
||||
table: subscriptions
|
||||
grain:
|
||||
- subscription_id
|
||||
columns:
|
||||
- name: subscription_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: canceled_at
|
||||
type: time
|
||||
role: time
|
||||
- name: churn_reason
|
||||
type: string
|
||||
- name: end_date
|
||||
type: time
|
||||
role: time
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
31
python/klo-sl/sources/b2b_saas/support_tickets.yaml
Normal file
31
python/klo-sl/sources/b2b_saas/support_tickets.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
name: support_tickets
|
||||
table: support_tickets
|
||||
grain:
|
||||
- ticket_id
|
||||
columns:
|
||||
- name: ticket_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: closed_at
|
||||
type: time
|
||||
role: time
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
- name: first_response_at
|
||||
type: time
|
||||
role: time
|
||||
- name: resolved_at
|
||||
type: time
|
||||
role: time
|
||||
- name: severity
|
||||
type: string
|
||||
- name: sla_breached
|
||||
type: string
|
||||
- name: status
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
16
python/klo-sl/sources/b2b_saas/target_accounts.yaml
Normal file
16
python/klo-sl/sources/b2b_saas/target_accounts.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
name: target_accounts
|
||||
table: target_accounts
|
||||
grain:
|
||||
- account_id
|
||||
columns:
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: start_date
|
||||
type: time
|
||||
role: time
|
||||
- name: target_tier
|
||||
type: string
|
||||
joins:
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
34
python/klo-sl/sources/b2b_saas/touchpoints.yaml
Normal file
34
python/klo-sl/sources/b2b_saas/touchpoints.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
name: touchpoints
|
||||
table: touchpoints
|
||||
grain:
|
||||
- touchpoint_id
|
||||
columns:
|
||||
- name: touchpoint_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: channel
|
||||
type: string
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: occurred_at
|
||||
type: time
|
||||
role: time
|
||||
- name: opportunity_id
|
||||
type: number
|
||||
- name: source_id
|
||||
type: number
|
||||
- name: source_object
|
||||
type: string
|
||||
- name: subchannel
|
||||
type: string
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: opportunities
|
||||
'on': opportunity_id = opportunities.opportunity_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
11
python/klo-sl/sources/b2b_saas/vendors.yaml
Normal file
11
python/klo-sl/sources/b2b_saas/vendors.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
name: vendors
|
||||
table: vendors
|
||||
grain:
|
||||
- vendor_id
|
||||
columns:
|
||||
- name: vendor_id
|
||||
type: number
|
||||
- name: category
|
||||
type: string
|
||||
- name: vendor_name
|
||||
type: string
|
||||
22
python/klo-sl/sources/b2b_saas/web_events.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/web_events.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: web_events
|
||||
table: web_events
|
||||
grain:
|
||||
- event_id
|
||||
columns:
|
||||
- name: event_id
|
||||
type: number
|
||||
- name: event_name
|
||||
type: string
|
||||
- name: event_time
|
||||
type: time
|
||||
role: time
|
||||
- name: page
|
||||
type: string
|
||||
- name: session_id
|
||||
type: number
|
||||
- name: value
|
||||
type: string
|
||||
joins:
|
||||
- to: web_sessions
|
||||
'on': session_id = web_sessions.session_id
|
||||
relationship: many_to_one
|
||||
30
python/klo-sl/sources/b2b_saas/web_sessions.yaml
Normal file
30
python/klo-sl/sources/b2b_saas/web_sessions.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
name: web_sessions
|
||||
table: web_sessions
|
||||
grain:
|
||||
- session_id
|
||||
columns:
|
||||
- name: session_id
|
||||
type: number
|
||||
- name: account_id
|
||||
type: number
|
||||
- name: landing_page
|
||||
type: string
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: session_start
|
||||
type: string
|
||||
- name: utm_campaign
|
||||
type: string
|
||||
- name: utm_medium
|
||||
type: string
|
||||
- name: utm_source
|
||||
type: string
|
||||
- name: visitor_id
|
||||
type: number
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: accounts
|
||||
'on': account_id = accounts.account_id
|
||||
relationship: many_to_one
|
||||
22
python/klo-sl/sources/b2b_saas/webinar_attendance.yaml
Normal file
22
python/klo-sl/sources/b2b_saas/webinar_attendance.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: webinar_attendance
|
||||
table: webinar_attendance
|
||||
grain:
|
||||
- attendance_id
|
||||
columns:
|
||||
- name: attendance_id
|
||||
type: number
|
||||
- name: attended
|
||||
type: string
|
||||
- name: duration_minutes
|
||||
type: number
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: webinar_id
|
||||
type: number
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: webinars
|
||||
'on': webinar_id = webinars.webinar_id
|
||||
relationship: many_to_one
|
||||
21
python/klo-sl/sources/b2b_saas/webinar_registrations.yaml
Normal file
21
python/klo-sl/sources/b2b_saas/webinar_registrations.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: webinar_registrations
|
||||
table: webinar_registrations
|
||||
grain:
|
||||
- registration_id
|
||||
columns:
|
||||
- name: registration_id
|
||||
type: number
|
||||
- name: lead_id
|
||||
type: number
|
||||
- name: registered_at
|
||||
type: time
|
||||
role: time
|
||||
- name: webinar_id
|
||||
type: number
|
||||
joins:
|
||||
- to: leads
|
||||
'on': lead_id = leads.lead_id
|
||||
relationship: many_to_one
|
||||
- to: webinars
|
||||
'on': webinar_id = webinars.webinar_id
|
||||
relationship: many_to_one
|
||||
19
python/klo-sl/sources/b2b_saas/webinars.yaml
Normal file
19
python/klo-sl/sources/b2b_saas/webinars.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: webinars
|
||||
table: webinars
|
||||
grain:
|
||||
- webinar_id
|
||||
columns:
|
||||
- name: webinar_id
|
||||
type: number
|
||||
- name: cost
|
||||
type: string
|
||||
- name: end_time
|
||||
type: time
|
||||
role: time
|
||||
- name: host_platform
|
||||
type: string
|
||||
- name: start_time
|
||||
type: time
|
||||
role: time
|
||||
- name: title
|
||||
type: string
|
||||
35
python/klo-sl/sources/ecommerce/churn_risk.yaml
Normal file
35
python/klo-sl/sources/ecommerce/churn_risk.yaml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
name: churn_risk
|
||||
description: |
|
||||
Customer churn risk score combining tenure,
|
||||
usage trends, and support burden.
|
||||
sql: |
|
||||
SELECT
|
||||
c.id AS customer_id,
|
||||
c.name AS customer_name,
|
||||
calculate_churn_score(c.id) AS score,
|
||||
CASE
|
||||
WHEN c.arr < 50000 THEN 'SMB'
|
||||
WHEN c.arr < 500000 THEN 'Mid-Market'
|
||||
ELSE 'Enterprise'
|
||||
END AS customer_type
|
||||
FROM customers c
|
||||
JOIN usage_summary u ON c.id = u.customer_id
|
||||
JOIN ticket_summary t ON c.id = t.customer_id
|
||||
grain: [customer_id]
|
||||
columns:
|
||||
- name: customer_id
|
||||
type: number
|
||||
- name: customer_name
|
||||
type: string
|
||||
- name: score
|
||||
type: number
|
||||
- name: customer_type
|
||||
type: string
|
||||
joins:
|
||||
- to: customers
|
||||
"on": customer_id = customers.id
|
||||
relationship: many_to_one
|
||||
measures:
|
||||
- name: avg_risk
|
||||
expr: avg(score)
|
||||
description: "Average churn risk score"
|
||||
19
python/klo-sl/sources/ecommerce/customers.yaml
Normal file
19
python/klo-sl/sources/ecommerce/customers.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
name: customers
|
||||
table: public.customers
|
||||
grain: [id]
|
||||
columns:
|
||||
- name: id
|
||||
type: number
|
||||
- name: name
|
||||
type: string
|
||||
- name: segment
|
||||
type: string
|
||||
- name: region_id
|
||||
type: number
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: regions
|
||||
"on": region_id = regions.id
|
||||
relationship: many_to_one
|
||||
21
python/klo-sl/sources/ecommerce/order_items.yaml
Normal file
21
python/klo-sl/sources/ecommerce/order_items.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: order_items
|
||||
table: public.order_items
|
||||
grain: [id]
|
||||
columns:
|
||||
- name: id
|
||||
type: number
|
||||
- name: order_id
|
||||
type: number
|
||||
- name: product_id
|
||||
type: number
|
||||
- name: quantity
|
||||
type: number
|
||||
- name: price
|
||||
type: number
|
||||
joins:
|
||||
- to: orders
|
||||
"on": order_id = orders.id
|
||||
relationship: many_to_one
|
||||
- to: products
|
||||
"on": product_id = products.id
|
||||
relationship: many_to_one
|
||||
39
python/klo-sl/sources/ecommerce/orders.yaml
Normal file
39
python/klo-sl/sources/ecommerce/orders.yaml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
name: orders
|
||||
table: public.orders
|
||||
grain: [id]
|
||||
columns:
|
||||
- name: id
|
||||
type: number
|
||||
- name: customer_id
|
||||
type: number
|
||||
- name: amount
|
||||
type: number
|
||||
- name: cost
|
||||
type: number
|
||||
- name: status
|
||||
type: string
|
||||
- name: created_at
|
||||
type: time
|
||||
role: time
|
||||
joins:
|
||||
- to: customers
|
||||
"on": customer_id = customers.id
|
||||
relationship: many_to_one
|
||||
measures:
|
||||
- name: revenue
|
||||
expr: sum(amount)
|
||||
filter: "status != 'refunded'"
|
||||
description: "Net revenue excluding refunds"
|
||||
- name: order_count
|
||||
expr: count(id)
|
||||
- name: total_amount
|
||||
expr: sum(amount)
|
||||
description: "Total order amount across all statuses"
|
||||
- name: paid_amount
|
||||
expr: sum(amount)
|
||||
filter: "status = 'paid'"
|
||||
description: "Total amount from paid orders only"
|
||||
- name: refunded_amount
|
||||
expr: sum(amount)
|
||||
filter: "status = 'refunded'"
|
||||
description: "Total amount from refunded orders"
|
||||
12
python/klo-sl/sources/ecommerce/products.yaml
Normal file
12
python/klo-sl/sources/ecommerce/products.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name: products
|
||||
table: public.products
|
||||
grain: [id]
|
||||
columns:
|
||||
- name: id
|
||||
type: number
|
||||
- name: name
|
||||
type: string
|
||||
- name: category
|
||||
type: string
|
||||
- name: price
|
||||
type: number
|
||||
8
python/klo-sl/sources/ecommerce/regions.yaml
Normal file
8
python/klo-sl/sources/ecommerce/regions.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
name: regions
|
||||
table: public.regions
|
||||
grain: [id]
|
||||
columns:
|
||||
- name: id
|
||||
type: number
|
||||
- name: name
|
||||
type: string
|
||||
27
python/klo-sl/sources/tpch/customer.yaml
Normal file
27
python/klo-sl/sources/tpch/customer.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: customer
|
||||
table: public.customer
|
||||
grain: [c_custkey]
|
||||
columns:
|
||||
- name: c_custkey
|
||||
type: number
|
||||
- name: c_name
|
||||
type: string
|
||||
- name: c_address
|
||||
type: string
|
||||
- name: c_nationkey
|
||||
type: number
|
||||
- name: c_phone
|
||||
type: string
|
||||
- name: c_acctbal
|
||||
type: number
|
||||
- name: c_mktsegment
|
||||
type: string
|
||||
- name: c_comment
|
||||
type: string
|
||||
joins:
|
||||
- to: nation
|
||||
"on": c_nationkey = nation.n_nationkey
|
||||
relationship: many_to_one
|
||||
measures:
|
||||
- name: customer_count
|
||||
expr: count(c_custkey)
|
||||
69
python/klo-sl/sources/tpch/lineitem.yaml
Normal file
69
python/klo-sl/sources/tpch/lineitem.yaml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
name: lineitem
|
||||
table: public.lineitem
|
||||
grain: [l_orderkey, l_linenumber]
|
||||
columns:
|
||||
- name: l_orderkey
|
||||
type: number
|
||||
- name: l_partkey
|
||||
type: number
|
||||
- name: l_suppkey
|
||||
type: number
|
||||
- name: l_linenumber
|
||||
type: number
|
||||
- name: l_quantity
|
||||
type: number
|
||||
- name: l_extendedprice
|
||||
type: number
|
||||
- name: l_discount
|
||||
type: number
|
||||
- name: l_tax
|
||||
type: number
|
||||
- name: l_returnflag
|
||||
type: string
|
||||
- name: l_linestatus
|
||||
type: string
|
||||
- name: l_shipdate
|
||||
type: time
|
||||
role: time
|
||||
- name: l_commitdate
|
||||
type: time
|
||||
- name: l_receiptdate
|
||||
type: time
|
||||
- name: l_shipinstruct
|
||||
type: string
|
||||
- name: l_shipmode
|
||||
type: string
|
||||
- name: l_comment
|
||||
type: string
|
||||
joins:
|
||||
- to: orders
|
||||
"on": l_orderkey = orders.o_orderkey
|
||||
relationship: many_to_one
|
||||
- to: part
|
||||
"on": l_partkey = part.p_partkey
|
||||
relationship: many_to_one
|
||||
- to: supplier
|
||||
"on": l_suppkey = supplier.s_suppkey
|
||||
relationship: many_to_one
|
||||
measures:
|
||||
- name: revenue
|
||||
expr: sum(l_extendedprice * (1 - l_discount))
|
||||
description: "Net revenue (TPC-H Q1 pricing)"
|
||||
- name: charge
|
||||
expr: sum(l_extendedprice * (1 - l_discount) * (1 + l_tax))
|
||||
description: "Charge including tax"
|
||||
- name: total_quantity
|
||||
expr: sum(l_quantity)
|
||||
- name: avg_quantity
|
||||
expr: avg(l_quantity)
|
||||
- name: avg_price
|
||||
expr: avg(l_extendedprice)
|
||||
- name: avg_discount
|
||||
expr: avg(l_discount)
|
||||
- name: line_count
|
||||
expr: count(l_orderkey)
|
||||
description: "Count of line items"
|
||||
- name: returned_revenue
|
||||
expr: sum(l_extendedprice * (1 - l_discount))
|
||||
filter: "l_returnflag = 'R'"
|
||||
description: "Revenue from returned items"
|
||||
16
python/klo-sl/sources/tpch/nation.yaml
Normal file
16
python/klo-sl/sources/tpch/nation.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
name: nation
|
||||
table: public.nation
|
||||
grain: [n_nationkey]
|
||||
columns:
|
||||
- name: n_nationkey
|
||||
type: number
|
||||
- name: n_name
|
||||
type: string
|
||||
- name: n_regionkey
|
||||
type: number
|
||||
- name: n_comment
|
||||
type: string
|
||||
joins:
|
||||
- to: region
|
||||
"on": n_regionkey = region.r_regionkey
|
||||
relationship: many_to_one
|
||||
36
python/klo-sl/sources/tpch/orders.yaml
Normal file
36
python/klo-sl/sources/tpch/orders.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: orders
|
||||
table: public.orders
|
||||
grain: [o_orderkey]
|
||||
columns:
|
||||
- name: o_orderkey
|
||||
type: number
|
||||
- name: o_custkey
|
||||
type: number
|
||||
- name: o_orderstatus
|
||||
type: string
|
||||
- name: o_totalprice
|
||||
type: number
|
||||
- name: o_orderdate
|
||||
type: time
|
||||
role: time
|
||||
- name: o_orderpriority
|
||||
type: string
|
||||
- name: o_clerk
|
||||
type: string
|
||||
- name: o_shippriority
|
||||
type: number
|
||||
- name: o_comment
|
||||
type: string
|
||||
joins:
|
||||
- to: customer
|
||||
"on": o_custkey = customer.c_custkey
|
||||
relationship: many_to_one
|
||||
measures:
|
||||
- name: order_count
|
||||
expr: count(o_orderkey)
|
||||
- name: total_price
|
||||
expr: sum(o_totalprice)
|
||||
description: "Total order value"
|
||||
- name: avg_order_value
|
||||
expr: avg(o_totalprice)
|
||||
description: "Average order value"
|
||||
22
python/klo-sl/sources/tpch/part.yaml
Normal file
22
python/klo-sl/sources/tpch/part.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: part
|
||||
table: public.part
|
||||
grain: [p_partkey]
|
||||
columns:
|
||||
- name: p_partkey
|
||||
type: number
|
||||
- name: p_name
|
||||
type: string
|
||||
- name: p_mfgr
|
||||
type: string
|
||||
- name: p_brand
|
||||
type: string
|
||||
- name: p_type
|
||||
type: string
|
||||
- name: p_size
|
||||
type: number
|
||||
- name: p_container
|
||||
type: string
|
||||
- name: p_retailprice
|
||||
type: number
|
||||
- name: p_comment
|
||||
type: string
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue