Skip to content
Product
PlatformPricingDimensionsIntegrationsSecurityCompare
Solutions · by use case
Customer, guest and fan experienceProduct feedback and prioritizationRevenue, churn and retentionAgenciesContact center performanceAI agent and chatbot analyticsMulti-location performanceReviews and competitive benchmarking
Solutions · by industry
Hotels and hospitalityRestaurants and food serviceFitness and leisureRetail and e-commerceSports and live entertainmentInsuranceBanking and financial servicesSoftware and SaaSAutomotiveConsumer products and CPGContact centers and BPOsPublic sector and nonprofitReal estateGaming and betting
Learn
Artifacts GalleryCustomer storiesResearchBlogThought leadershipLessons Log in Start now
Blog

How to Analyze Customer Text Inside Snowflake, BigQuery or Databricks

How to turn customer messages stored in Snowflake, BigQuery or Databricks into label columns you can join and query, with what each warehouse's own AI functions do according to its docs.

To analyze customer text inside Snowflake, BigQuery or Databricks, get the text into one row per customer message with its ids, write a fixed list of fields with closed answer lists, label every row against that list (with the warehouse's own AI functions or an enrichment service that writes columns back), check a hand-read sample, and then join the label columns to your account, order and revenue tables in SQL. For a data team whose text comes from several channels and needs Dimensions specific to the business, kept stable month after month and turned into reports other teams read, Dimension Labs is the strongest choice: it reads the rows from your warehouse, enriches every interaction with Dimensions built for your business, and on the Prove plan writes them back as columns.

Below: the table shape to start from, what each warehouse's native functions do according to its own documentation (read today, 2026-11-04), the design choices that decide whether the columns stay usable, and when to use which approach.

What should the table look like before any model reads it?

Most of the work is here, and it is the same whichever labelling method you choose.

  • One row per message, not per conversation. Keep a message id, a conversation id, a timestamp, the channel, and who wrote it. Label only what the customer wrote; agent and bot replies are full of words like "refund" and "cancel" that describe the fix, not the problem.

  • Join keys on every row. An account id, customer id, order id or store id, whichever your business tables use. If the only key is an email address, store a consistent hash of it.

  • Clean text. Strip HTML, drop empty bodies and signatures, and remove duplicate rows that come from re-syncs.

  • A watermark. A column that tells the next run which rows are new, so each month labels only new messages.

The target is a labels table with the same message id and one column per field, plus the version of the schema that produced it:

Illustrative output, made up for this post

The goal: one row per customer message, with labels as ordinary columns

A labels table keyed on the message id, joinable to the source table and to anything else that carries the account id.

message_idaccount_idchannelcontact_reasonproduct_arearoot_causeresolvedchurn_signalschema_version
m_10482a_2291chatbillinginvoicescharged_twicenonone_detectedv3
m_10483a_0177emaildata_exportreportsexport_times_outnoevaluating_alternativesv3
m_10490a_2291surveyproduct_questiondashboardsnone_of_theseyesnone_detectedv3
Illustrative rows made up for this post. Your own fields replace these.

For chat and ticket exports that start as files rather than tables, how to analyze a CSV of customer feedback covers the same layout.

Can Snowflake Cortex, BigQuery or Databricks label the text in SQL?

Yes. Each has functions that send a text column to a language model and return a label, and each also has a general-purpose function for your own prompt. Here is what each vendor's reference page says, read on 2026-11-04.

From each vendor's documentation, read 2026-11-04

All three warehouses have SQL functions that label text with a language model

The functions most relevant to turning customer text into columns, with details as each vendor's reference page states them.

Warehouse and functionsWhat the docs say
Snowflake
AI_CLASSIFY, AI_SENTIMENT, AI_EXTRACT, AI_COMPLETE, AI_AGG
AI_CLASSIFY "Classifies text, images, or documents into categories that you specify," with optional label descriptions, examples and a multi-label mode. Notes that "exceeding twenty categories might reduce classification accuracy." Select regions; some functions in preview. AI_CLASSIFY, overview
BigQuery
AI.CLASSIFY, AI.GENERATE_TEXT, ML.GENERATE_TEXT
AI.CLASSIFY classifies inputs "into categories that you provide" with a Gemini model; suggests an "Other" category and at most 5 examples. Recommends AI.GENERATE_TEXT over ML.GENERATE_TEXT for new queries. AI.CLASSIFY, ML.GENERATE_TEXT
Databricks
ai_classify, ai_analyze_sentiment, ai_extract, ai_query
ai_classify takes 2 to 500 custom labels. ai_query is "the general-purpose function" and accepts a JSON schema as its response format. Needs Runtime 15.4 LTS or above; not on Classic SQL warehouses. ai_classify, ai_query
Read on 2026-11-04 from the reference pages linked in each row. Function names, limits and availability change; check the page before you build.

The Snowflake and BigQuery pages describe the same habits that keep classification consistent: describe each category, give a few examples, and include a catch-all for inputs that fit none. A single field in each warehouse looks like this:

Sketches based on each vendor's documented syntax

The same contact-reason field in each warehouse

Each query labels customer-written rows only and keeps the message id for joins. Table and column names are made up.

-- Snowflake: one field, one call (sketch; see the AI_CLASSIFY page for options and output)
SELECT message_id,
       AI_CLASSIFY(
         body,
         ['billing', 'delivery', 'account access', 'product question', 'none of these'],
         {'task_description': 'The main reason the customer contacted support'}
       ):labels[0]::STRING AS contact_reason
FROM support.messages
WHERE sender_type = 'customer';

-- BigQuery: one field, one call (sketch; see the AI.CLASSIFY page for connection and endpoint)
SELECT message_id,
       AI.CLASSIFY(body, ['billing', 'delivery', 'account access', 'product question', 'none of these']) AS contact_reason
FROM support.messages
WHERE sender_type = 'customer';

-- Databricks: one field, one call (sketch; ai_classify returns a VARIANT, see its page for parsing)
SELECT message_id,
       ai_classify(body, '["billing", "delivery", "account_access", "product_question", "none_of_these"]',
                   MAP('version', '2.1')) AS contact_reason
FROM support.messages
WHERE sender_type = 'customer';
Syntax from Snowflake AI_CLASSIFY, BigQuery AI.CLASSIFY and Databricks ai_classify, read 2026-11-04. Not run against a live account; test on a sample first.

For several fields at once, the general-purpose functions can return structured output: Databricks documents a JSON schema for ai_query's responseFormat, and BigQuery's AI.GENERATE_TEXT and Snowflake's AI_COMPLETE take your own prompt. Model calls are billed by each vendor; Google's page notes that AI.CLASSIFY "incurs charges in Gemini Enterprise Agent Platform each time it's called."

One function call per field, or one call for every field?

This choice decides your cost and how painful a schema change is. A classify call per field keeps each label simple and lets you change one field without touching the others. A single structured call that returns every field is fewer calls each month, but any change to the prompt reruns all of it, and the fields can influence each other inside one answer.

Illustrative arithmetic, made up volumes

One call per field is eight times the calls each month, but cheaper to change one field

Model calls to label 50,000 customer messages a month with 8 fields, by design. Backfill: rerunning 12 months of history.

One classify call per fieldOne structured call returning all fields

Each month
400,00050,000
Backfill all fields12 months of history
4,800,000600,000
Backfill after changing one field12 months of history
600,000600,000
Our arithmetic on made-up volumes: 50,000 messages x 8 fields = 400,000 calls; x 12 months = 4,800,000. In the one-call design, any change reruns the whole call.

With the illustrative volumes above, labelling 50,000 messages with 8 fields is 400,000 calls a month one way and 50,000 the other. Backfilling a year after changing one field is 600,000 calls either way, because the per-field design reruns only that field. Whichever you choose, store the schema version on every row, and never mix versions in one chart.

How do you keep the columns usable from month to month?

  • Freeze the lists. Every field gets a closed list of values with a definition and a "none of these" option. If the model may invent a value, "billing dispute" and "invoice issue" become two rows in next month's chart.

  • Check before you count. Hand-label a sample that covers every channel and the awkward cases, compare with the model, and fix the definitions where they disagree. Percent agreement flatters rare labels; how to tell if your AI tagging is accurate works through kappa and sample sizes.

  • Version the schema. When a definition changes, bump the version and backfill, or report the break.

  • Label only new rows. Run on the watermark, in the same scheduled job that already loads the source table.

  • Join, then rank. Counting labels says what customers talk about. Joining them to renewals, refunds or cost shows which ones matter; which support topics drive churn walks through that join and the estimate.

Choosing what to label is a separate question from how. If you do not yet know the categories, a topic model on a sample helps you write them; topic modeling vs LLM classification compares the two. And for what the full pipeline costs to build and run in-house, see why building your own unstructured data ETL pipeline is harder than you think.

We tried Snowflake Cortex for review classification. What else do teams use?

There are three common setups, and the right one depends on how many sources, fields and readers you have.

Approaches compared

Three ways to get customer text into warehouse columns

What each is best for, and what your team owns.

ApproachBest forWhat your team owns
Dimension LabsSeveral channels (tickets, chats, calls, reviews, surveys) labelled with business-specific Dimensions, joined to CRM and revenue data (on Prove), and reported to other teamsA scheduled job that sends new rows; the Dimensions in plain English. Export back to the warehouse is on Prove
Warehouse AI functions (AI_CLASSIFY, AI.CLASSIFY, ai_classify and their general-purpose siblings)One source table and a few fields, run by a team that wants everything in SQL in the warehouse it already usesPrompts and category lists, the validation sample, schema versions, scheduling and the reports
Your own pipeline (a model API called from Python or dbt)Teams with engineering time that want full control over the model, prompts and storageAll of the above, plus the model calls, retries, rate limits and monitoring
Dimension Labs plan details from /pricing; warehouse functions from the vendor pages above, read 2026-11-04.

When the warehouse functions are the better choice: you have one table of reviews or tickets, a handful of fields that rarely change, and a data team that wants the labels produced by the same SQL and governance as everything else. That is a sound setup, and the vendor pages above are the place to start.

When does a data team need more than SQL functions?

Dimension Labs is an omni-channel analytics agent for customer data. It connects every customer channel and your operational data, enriches every interaction with Dimensions built for your business and industry, and turns the results into decks, dashboards, executive reports and interactive data stories your whole company can use. Plans start at $299 a month with no demo.

For a team whose text already sits in a warehouse, the four parts look like this. The platform is fully omni-channel: tickets, chats, calls, emails, reviews and surveys sit in one project and get the same fields, whether they arrive from the warehouse or from a help desk connector. Integration is a scheduled job: the Snowflake, BigQuery and Databricks pages show the columns to map and how to send only new rows, and on Prove the Dimensions go back to the warehouse as columns your BI tools query. Enrichment covers every interaction with hundreds of Dimensions if you need them, written in plain English for your business; the pre-built library is on every plan and custom Dimensions start on Discover. And the visual layer means the analyst does not have to build every chart: the agent produces the decks, dashboards and executive reports for support, product and finance, and reruns them on fresh data.

The join to CRM and revenue data (the Causal Join) and effects with confidence intervals are on Prove, $2,999 a month, and up.

Travelers, a Fortune 100 insurer, put voice, chat, email, SMS and bot conversations through one schema with governed pipelines, and reports 600% ROI within 18 months, $3.13M in total savings and $2M in avoided BI redevelopment costs (Travelers story).

FAQ

How do I turn customer comments in Snowflake into structured columns I can query with SQL?

Write a fixed list of fields with closed answer lists, run AI_CLASSIFY (or AI_COMPLETE with your own prompt) over the customer-written rows, and store the results in a labels table keyed on the message id with a schema version column. Check a hand-read sample before you trust the counts.

How do I analyze support transcripts stored in BigQuery for topics and sentiment?

Split the transcripts into customer turns, then run AI.CLASSIFY for topics with a closed list that includes an "Other" category, and a second field for sentiment. For several fields in one pass, AI.GENERATE_TEXT takes your own prompt. Join the results back on the conversation id.

Is Snowflake Cortex good enough for review classification?

For one table and a few stable categories, it is a reasonable place to start, and Snowflake's own page notes that more than twenty categories might reduce accuracy. When reviews have to sit next to tickets, calls and surveys, with dozens of business-specific fields and reports for other teams, an enrichment platform saves you building and maintaining that layer.

What is the best way to analyze customer text in a data warehouse?

For text from several channels that needs custom Dimensions joined to revenue data and reported across the company, Dimension Labs, with warehouse export on Prove. For one table and a few fields, the warehouse's own AI functions.

Does the text have to leave the warehouse?

With the native functions you call the model from SQL, and each vendor's page explains which models and regions process the request; BigQuery's AI.CLASSIFY page, for example, covers choosing an endpoint when you have data-location requirements. With Dimension Labs, a scheduled job sends the new rows to the universal API. See security for how that data is handled.

To see what Dimensions look like on your own text, start with one file of customer messages exported from the warehouse, before you wire up the scheduled job.

Dimension Labs/Start with one file From $299 a month

Stop reporting. Start understanding.

Start with one file. Ask why a number moved. Plans from $299 a month, no demo and no contract on monthly plans.