SQL Analysis
& Reporting

Querying the Voice of Customer Repository · intellimation.ai

The Project

The same Voice of Customer repository, seen through a different lens: not who asked what, but what the data says at scale.

My Enterprise AI Product Marketing case study covers how I built intellimation.ai's Voice of Customer repository from zero: capturing and categorising customer questions from every demo, POC and client meeting into a shared source of truth. This case study picks up from there, treating that repository as a dataset and querying it directly in SQL to surface patterns no single conversation could show on its own.

Building the repository and analysing it were two different disciplines, done by the same person for the same programme. Every number, table and chart below comes directly from the underlying question log. Nothing here is modelled, projected, or rounded up for effect.

Scope Cross-Product Cross-Region
Method SQL Analysis Data Modelling KPI Reporting Dashboard Design
Data Range Apr 2024 – Sep 2025 Repository history
Results 749 Rows Analysed 3 Pillars Benchmarked 12 Regions Compared See the source repository ↗

The Data Model

One flat question log, captured at the point of every demo, POC and client meeting. No pre-aggregation, no cleaning applied at source. That part came later, in SQL.

Schema: voc_questions
question_id       text        -- e.g. Q-001
log_date          date        -- meeting date
company_type_raw  text        -- captured free-text at intake (messy)
region            text        -- client HQ / desk region
pillar            text        -- product line, tagged inconsistently
sales_stage       text        -- free-text sales stage at time of capture
question_type     text        -- Functional / Technical / Strategic / Commercial / Compliance
question_text     text
answer_text       text

Company type and region were captured reliably: tagged on 98% and 86% of rows. Pillar, sales stage and question category were not, which is where the analysis had to start.

Data Quality Before Insight

Before asking what the data said, I had to know how much of it could be trusted. The honest answer, for three of six fields, was: not much yet.

SQL: tagging completeness by field
SELECT
  COUNT(*)                                            AS total_questions,
  COUNT(pillar)                                       AS pillar_tagged,
  COUNT(sales_stage)                                  AS stage_tagged,
  COUNT(question_type)                                AS category_tagged,
  ROUND(COUNT(pillar)       * 100.0 / COUNT(*), 1)    AS pct_pillar,
  ROUND(COUNT(sales_stage)  * 100.0 / COUNT(*), 1)    AS pct_stage,
  ROUND(COUNT(question_type)* 100.0 / COUNT(*), 1)    AS pct_category
FROM voc_questions;
Result
total_questionspillar_taggedstage_taggedcategory_taggedpct_pillarpct_stagepct_category
74916116422821.5%21.9%30.4%
Fewer than 1 in 4 questions carried a product pillar or sales-stage tag at the point of capture, against 98% for company type and 86% for region. That gap, not a modelling choice, is what shaped the rest of this analysis: every pillar- and stage-level result below is a finding about the tagged subset, stated as such.

Cleaning the Categorical Fields

Company type was captured as free text, so the same segment showed up under slightly different labels. A CASE statement standardised it before anything else could be trusted.

SQL: CASE + GROUP BY + COUNT
SELECT
  CASE
    WHEN company_type_raw IN ('Tier 2 Regional Bank', 'Tier 2 / Regional Bank')
      THEN 'Tier 2 / Regional Bank'
    WHEN company_type_raw IN ('Vendor / Consulting', 'Consulting / Vendor')
      THEN 'Consulting / Vendor'
    WHEN company_type_raw = 'Asset Management'
      THEN 'Asset Manager / Investment'
    ELSE COALESCE(company_type_raw, '(untagged)')
  END                       AS company_type,
  COUNT(*)                  AS questions
FROM voc_questions
GROUP BY 1
ORDER BY questions DESC;
Result: top segments (of 13 total)
company_typequestions
Tier 1 Bank260
Asset Manager / Investment223
Hedge Fund / Alternative105
Vendor / Fintech34
All other segments (9 categories)127

749 total. Tier 1 Banks and Asset Managers together account for nearly two-thirds of every question logged.

Where the Volume Comes From

Grouping the tagged subset by product pillar and by region, the two dimensions the business cared about most.

SQL: GROUP BY + window function (share of tagged total)
SELECT
  pillar,
  COUNT(*)                                              AS questions,
  ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 1)    AS pct_of_tagged
FROM voc_questions
WHERE pillar IS NOT NULL
GROUP BY pillar
ORDER BY questions DESC;
Questions by pillar (161 tagged)
Collateral Management
87
Structured Products
69
Direct Lending
5
SQL: GROUP BY + RANK()
SELECT
  region,
  COUNT(*)                                    AS questions,
  RANK() OVER (ORDER BY COUNT(*) DESC)        AS rank
FROM voc_questions
WHERE region IS NOT NULL
GROUP BY region
ORDER BY rank;
Questions by region (645 tagged, top 6 of 12)
United States
338
United Kingdom
183
Germany
35
Canada
19
Japan
17
Netherlands
17

Which Segments Care About Which Pillar

Joining the cleaned company-type view back to pillar tags surfaced a pattern clear enough to write straight into messaging.

SQL: JOIN + CASE + GROUP BY
SELECT
  c.company_type,
  SUM(CASE WHEN q.pillar = 'Collateral Management' THEN 1 ELSE 0 END) AS collateral_mgmt,
  SUM(CASE WHEN q.pillar = 'Structured Products'   THEN 1 ELSE 0 END) AS structured_products,
  SUM(CASE WHEN q.pillar = 'Direct Lending'         THEN 1 ELSE 0 END) AS direct_lending,
  SUM(CASE WHEN q.pillar IS NULL                    THEN 1 ELSE 0 END) AS untagged
FROM voc_questions q
JOIN dim_company_type_clean c ON c.raw_value = q.company_type_raw
WHERE c.company_type IN ('Tier 1 Bank','Asset Manager / Investment','Hedge Fund / Alternative')
GROUP BY c.company_type
ORDER BY untagged DESC;
Result
company_typecollateral_mgmtstructured_productsdirect_lendinguntagged
Tier 1 Bank33254198
Asset Manager / Investment3500188
Hedge Fund / Alternative344058
Once untagged rows are set aside, Hedge Funds' tagged questions are almost entirely about Structured Products (44 of 47), Asset Managers' are exclusively about Collateral Management (35 of 35), and Tier 1 Banks are the only segment asking across all three pillars. That's a real segment-to-pillar affinity, not an assumption, and it's the kind of pattern a single sales conversation never surfaces on its own.

Fixing the Sales Stage Field

Sales stage was free text at capture: "1st", "Presentation", "Needs analysis" and a handful of values that were clearly meant for a different column entirely. A small lookup table cleaned it up.

SQL: LEFT JOIN to a funnel-stage lookup table
-- dim_stage_bucket(raw_stage, funnel_stage) maps messy free-text
-- stage values onto four clean funnel buckets
SELECT
  COALESCE(b.funnel_stage, 'Untagged') AS funnel_stage,
  COUNT(*)                             AS questions
FROM voc_questions q
LEFT JOIN dim_stage_bucket b
  ON q.sales_stage = b.raw_stage
GROUP BY 1
ORDER BY questions DESC;
Result
funnel_stagequestions
Untagged585
Presentation67
Discovery47
Qualification44
Miscategorised (technical/functional labels found in this field)4
Closed2

The 4 "miscategorised" rows had question-category values ("Technical (deployment/integration)", "Functional (features/workflows)") entered into the sales-stage field, a genuine intake error worth flagging back to the capture process, not something to quietly merge away.

Momentum Over Time

A running total by quarter, using a window function over the 733 rows with a usable log date.

SQL: window function (running total)
SELECT
  quarter,
  questions,
  SUM(questions) OVER (ORDER BY quarter) AS cumulative_questions
FROM (
  SELECT
    CONCAT(EXTRACT(YEAR FROM log_date), '-Q', EXTRACT(QUARTER FROM log_date)) AS quarter,
    COUNT(*) AS questions
  FROM voc_questions
  WHERE log_date IS NOT NULL
  GROUP BY 1
) quarterly
ORDER BY quarter;
Result (16 rows excluded, missing or malformed log_date)
quarterquestionscumulative_questions
2024-Q2126126
2024-Q3219345
2024-Q453398
2025-Q135433
2025-Q2176609
2025-Q3124733
The 2024-Q3 spike is one long, detailed technical deep-dive with a single prospect, not a shift in overall inbound demand, the kind of outlier a raw growth chart would misread if you didn't check what was actually behind it before writing it into a report.

From Query to Dashboard

The version of this that actually got looked at week to week: KPI tiles up top, the two distributions that mattered underneath.

Voice of Customer: Repository Overview Apr 2024 – Sep 2025
749Questions logged
12Regions represented
3Pillars tracked
21.5%Pillar-tagged at capture
By pillar (tagged)
Collateral Mgmt
87
Structured Products
69
Direct Lending
5
By segment (cleaned)
Tier 1 Bank
260
Asset Manager
223
Hedge Fund
105

What the Analysis Was Used For

Not a separate deliverable: the evidence layer underneath the product marketing programme.

This SQL work fed directly into the programme described in the Enterprise AI Product Marketing case study. Flagging how much pillar, stage and category metadata was missing led to a simpler tagging process at the point of capture going forward. Confirming which client segments asked about which pillar gave the messaging work an evidence base instead of a hunch. And tracking the repository's growth quarter over quarter kept the underlying dataset honest, including catching when a single detailed session, not a real shift in demand, explained a spike.

Two disciplines, one repository: building it, and analysing it.

Next project
Brand Strategy & Digital Experience