Dremio Blog

28 minute read · February 27, 2026

Build a Customer 360 View on Dremio Cloud

Alex Merced Alex Merced Head of DevRel, Dremio
Start For Free
Build a Customer 360 View on Dremio Cloud
Copied to clipboard

A unified customer view is one of the most requested analytics projects in any organization. Customer data sits in the CRM. Purchase history lives in the e-commerce database. Support tickets are stored somewhere else entirely. No single team sees the full picture.

This tutorial walks you through building a complete Customer 360 view on Dremio Cloud, from signup to asking natural language questions about your customers. You'll seed sample data, model it through Bronze, Silver, and Gold views, enable AI-generated documentation, and use Dremio's built-in AI Agent to generate insights and charts. The entire process takes about 30 minutes with a free trial account.

What You'll Build

By the end of this tutorial, you'll have:

  • Source tables simulating a CRM (PostgreSQL), an e-commerce platform (MySQL), and a support system (MongoDB)
  • Bronze views that clean and standardize raw data
  • Silver views that join customer records with purchases and support tickets
  • Gold views with business metrics like customer lifetime value and customer health score
  • AI-generated wikis and tags that teach the AI Agent what each metric means
  • Natural language analytics powered by the AI Agent

Try Dremio’s Interactive Demo

Explore this interactive demo and see how Dremio's Intelligent Lakehouse enables Agentic AI

Step 1: Sign Up for Dremio Cloud

Go to dremio.com/get-started and create a free trial account. The trial gives you 30 days and $400 in compute credits.

When you log in, you'll land on the homepage with the AI Agent chat box. Your trial comes pre-configured with:

  • project (your analytics workspace)
  • An Open Catalog built on Apache Polaris (your built-in data catalog)
  • Dremio-managed storage (no need to connect your own S3 bucket)

You don't need to connect any external data sources to follow this tutorial. Everything runs inside the built-in catalog.

Navigate to the SQL Runner using the left sidebar. This is where you'll execute all the SQL in this tutorial.

Step 2: Create Folders and Seed Data

First, create a folder structure that simulates different source systems. In a production environment, these would be federated connections to actual databases. Here, we're using folders to organize the data the same way it would look with real sources.

CREATE FOLDER IF NOT EXISTS customer360exp;
CREATE FOLDER IF NOT EXISTS customer360exp.postgres;
CREATE FOLDER IF NOT EXISTS customer360exp.mysql;
CREATE FOLDER IF NOT EXISTS customer360exp.mongo;

Note: Because these tables live in the built-in Open Catalog, you reference them as folder.subfolder.table_name without a catalog prefix. When you connect external sources (PostgreSQL, S3, Snowflake), you'd use source_name.schema.table_name.

Now seed the tables. Each table has 50+ records to give the AI Agent enough data to generate meaningful analytics.

Customers Table (CRM)

CREATE TABLE customer360exp.postgres.customers (
  customer_id INT,
  first_name VARCHAR,
  last_name VARCHAR,
  email VARCHAR,
  segment VARCHAR,
  region VARCHAR,
  signup_date DATE
);

INSERT INTO customer360exp.postgres.customers VALUES
(1,'Alice','Chen','[email protected]','Enterprise','APAC','2023-01-15'),
(2,'Bob','Martinez','[email protected]','SMB','AMER','2023-02-20'),
(3,'Carol','Smith','[email protected]','Enterprise','EMEA','2022-11-03'),
(4,'David','Kim','[email protected]','Mid-Market','APAC','2023-04-10'),
(5,'Eva','Johnson','[email protected]','SMB','AMER','2023-05-22'),
(6,'Frank','Liu','[email protected]','Enterprise','APAC','2022-08-14'),
(7,'Grace','Patel','[email protected]','Mid-Market','EMEA','2023-03-01'),
(8,'Henry','Brown','[email protected]','SMB','AMER','2023-06-18'),
(9,'Iris','Wang','[email protected]','Enterprise','APAC','2022-12-05'),
(10,'Jack','Taylor','[email protected]','Mid-Market','EMEA','2023-07-09'),
(11,'Karen','Lee','[email protected]','Enterprise','AMER','2022-09-25'),
(12,'Leo','Garcia','[email protected]','SMB','AMER','2023-08-14'),
(13,'Mia','Nguyen','[email protected]','Mid-Market','APAC','2023-01-30'),
(14,'Nathan','Wilson','[email protected]','Enterprise','EMEA','2022-10-12'),
(15,'Olivia','Thomas','[email protected]','SMB','AMER','2023-09-05'),
(16,'Paul','Anderson','[email protected]','Enterprise','APAC','2022-07-20'),
(17,'Quinn','Davis','[email protected]','Mid-Market','AMER','2023-02-14'),
(18,'Rachel','Moore','[email protected]','SMB','EMEA','2023-10-01'),
(19,'Sam','Jackson','[email protected]','Enterprise','AMER','2022-06-30'),
(20,'Tina','White','[email protected]','Mid-Market','APAC','2023-04-25'),
(21,'Uma','Harris','[email protected]','Enterprise','EMEA','2023-11-11'),
(22,'Victor','Clark','[email protected]','SMB','AMER','2023-03-17'),
(23,'Wendy','Lewis','[email protected]','Mid-Market','APAC','2023-05-08'),
(24,'Xavier','Walker','[email protected]','Enterprise','AMER','2022-08-22'),
(25,'Yara','Hall','[email protected]','SMB','EMEA','2023-06-30'),
(26,'Zach','Allen','[email protected]','Enterprise','APAC','2022-11-15'),
(27,'Amy','Young','[email protected]','Mid-Market','AMER','2023-07-20'),
(28,'Brian','King','[email protected]','SMB','EMEA','2023-08-25'),
(29,'Chloe','Wright','[email protected]','Enterprise','APAC','2022-12-10'),
(30,'Derek','Scott','[email protected]','Mid-Market','AMER','2023-09-15'),
(31,'Elena','Green','[email protected]','Enterprise','EMEA','2023-01-05'),
(32,'Felix','Adams','[email protected]','SMB','APAC','2023-10-20'),
(33,'Gina','Baker','[email protected]','Mid-Market','AMER','2023-02-28'),
(34,'Hugo','Nelson','[email protected]','Enterprise','EMEA','2022-09-10'),
(35,'Ivy','Carter','[email protected]','SMB','APAC','2023-11-05'),
(36,'Jake','Mitchell','[email protected]','Enterprise','AMER','2022-07-15'),
(37,'Kira','Perez','[email protected]','Mid-Market','EMEA','2023-04-12'),
(38,'Liam','Roberts','[email protected]','SMB','AMER','2023-05-30'),
(39,'Maya','Turner','[email protected]','Enterprise','APAC','2022-10-25'),
(40,'Noah','Phillips','[email protected]','Mid-Market','EMEA','2023-06-14'),
(41,'Olga','Campbell','[email protected]','Enterprise','AMER','2022-08-05'),
(42,'Pete','Parker','[email protected]','SMB','APAC','2023-07-28'),
(43,'Rosa','Evans','[email protected]','Mid-Market','AMER','2023-08-10'),
(44,'Sean','Edwards','[email protected]','Enterprise','EMEA','2022-11-20'),
(45,'Tara','Collins','[email protected]','SMB','AMER','2023-09-22'),
(46,'Uri','Stewart','[email protected]','Enterprise','APAC','2022-12-30'),
(47,'Vera','Sanchez','[email protected]','Mid-Market','EMEA','2023-01-18'),
(48,'Will','Morris','[email protected]','SMB','AMER','2023-10-15'),
(49,'Xena','Rogers','[email protected]','Enterprise','APAC','2023-02-05'),
(50,'Yuri','Reed','[email protected]','Mid-Market','AMER','2023-11-30');

Orders Table (E-commerce)

CREATE TABLE customer360exp.mysql.orders (
  order_id INT,
  customer_id INT,
  order_date DATE,
  total_amount DECIMAL(10,2),
  status VARCHAR
);

INSERT INTO customer360exp.mysql.orders VALUES
(1001,1,'2024-01-10',2500.00,'completed'),
(1002,1,'2024-03-15',1800.00,'completed'),
(1003,2,'2024-02-05',350.00,'completed'),
(1004,3,'2024-01-22',4200.00,'completed'),
(1005,3,'2024-04-10',3100.00,'completed'),
(1006,4,'2024-03-01',890.00,'completed'),
(1007,5,'2024-02-14',210.00,'completed'),
(1008,6,'2024-01-30',5600.00,'completed'),
(1009,6,'2024-03-25',4100.00,'completed'),
(1010,6,'2024-05-12',3200.00,'completed'),
(1011,7,'2024-02-20',720.00,'completed'),
(1012,8,'2024-04-05',180.00,'completed'),
(1013,9,'2024-01-15',3800.00,'completed'),
(1014,9,'2024-03-30',2900.00,'completed'),
(1015,10,'2024-02-28',650.00,'completed'),
(1016,11,'2024-04-15',4500.00,'completed'),
(1017,11,'2024-06-01',3700.00,'completed'),
(1018,12,'2024-03-10',290.00,'completed'),
(1019,13,'2024-05-20',810.00,'completed'),
(1020,14,'2024-01-08',5100.00,'completed'),
(1021,14,'2024-04-22',4300.00,'completed'),
(1022,15,'2024-06-10',175.00,'completed'),
(1023,16,'2024-02-12',6200.00,'completed'),
(1024,16,'2024-05-05',4800.00,'completed'),
(1025,17,'2024-03-18',920.00,'completed'),
(1026,18,'2024-04-30',310.00,'completed'),
(1027,19,'2024-01-25',5500.00,'completed'),
(1028,19,'2024-04-08',4100.00,'completed'),
(1029,20,'2024-05-15',780.00,'completed'),
(1030,21,'2024-06-20',3900.00,'completed'),
(1031,22,'2024-03-05',260.00,'completed'),
(1032,23,'2024-04-18',850.00,'completed'),
(1033,24,'2024-02-08',4700.00,'completed'),
(1034,24,'2024-05-22',3600.00,'completed'),
(1035,25,'2024-06-05',220.00,'completed'),
(1036,26,'2024-01-20',5800.00,'completed'),
(1037,26,'2024-04-12',4400.00,'completed'),
(1038,27,'2024-03-28',940.00,'completed'),
(1039,28,'2024-05-10',340.00,'completed'),
(1040,29,'2024-02-15',3500.00,'completed'),
(1041,29,'2024-05-30',2800.00,'completed'),
(1042,30,'2024-04-25',710.00,'completed'),
(1043,31,'2024-06-15',4100.00,'completed'),
(1044,32,'2024-03-12',190.00,'completed'),
(1045,33,'2024-05-08',880.00,'completed'),
(1046,34,'2024-01-18',5300.00,'completed'),
(1047,35,'2024-04-02',250.00,'completed'),
(1048,36,'2024-02-22',4900.00,'completed'),
(1049,37,'2024-06-08',760.00,'completed'),
(1050,38,'2024-03-20',320.00,'completed');

Support Tickets Table

CREATE TABLE customer360exp.mongo.tickets (
  ticket_id INT,
  customer_id INT,
  created_date DATE,
  resolved_date DATE,
  priority VARCHAR,
  status VARCHAR,
  category VARCHAR
);

INSERT INTO customer360exp.mongo.tickets VALUES
(5001,1,'2024-02-10','2024-02-12','medium','resolved','billing'),
(5002,3,'2024-03-05','2024-03-06','high','resolved','technical'),
(5003,6,'2024-04-01',NULL,'high','open','technical'),
(5004,9,'2024-02-20','2024-02-21','low','resolved','general'),
(5005,11,'2024-05-10','2024-05-12','medium','resolved','billing'),
(5006,14,'2024-03-15',NULL,'critical','open','technical'),
(5007,16,'2024-04-20','2024-04-21','low','resolved','general'),
(5008,19,'2024-01-30','2024-02-01','high','resolved','technical'),
(5009,21,'2024-06-05',NULL,'medium','open','billing'),
(5010,24,'2024-03-22','2024-03-23','low','resolved','general'),
(5011,26,'2024-05-15',NULL,'high','open','technical'),
(5012,29,'2024-04-10','2024-04-12','medium','resolved','billing'),
(5013,31,'2024-06-18',NULL,'critical','open','technical'),
(5014,34,'2024-02-25','2024-02-26','low','resolved','general'),
(5015,36,'2024-05-01','2024-05-03','high','resolved','technical'),
(5016,39,'2024-03-30',NULL,'medium','open','billing'),
(5017,1,'2024-05-20','2024-05-21','low','resolved','general'),
(5018,4,'2024-04-15','2024-04-17','medium','resolved','billing'),
(5019,7,'2024-06-10',NULL,'high','open','technical'),
(5020,10,'2024-03-08','2024-03-09','low','resolved','general'),
(5021,13,'2024-05-25','2024-05-27','medium','resolved','billing'),
(5022,16,'2024-06-22',NULL,'high','open','technical'),
(5023,2,'2024-04-05','2024-04-06','low','resolved','general'),
(5024,5,'2024-02-18','2024-02-19','medium','resolved','billing'),
(5025,8,'2024-05-30',NULL,'high','open','technical'),
(5026,12,'2024-03-12','2024-03-13','low','resolved','general'),
(5027,15,'2024-06-01','2024-06-03','medium','resolved','billing'),
(5028,18,'2024-04-28',NULL,'high','open','technical'),
(5029,20,'2024-02-08','2024-02-09','low','resolved','general'),
(5030,22,'2024-05-18','2024-05-19','medium','resolved','billing'),
(5031,25,'2024-03-25',NULL,'critical','open','technical'),
(5032,27,'2024-06-12','2024-06-14','medium','resolved','billing'),
(5033,30,'2024-04-22','2024-04-23','low','resolved','general'),
(5034,33,'2024-02-15','2024-02-17','high','resolved','technical'),
(5035,35,'2024-05-08',NULL,'medium','open','billing'),
(5036,37,'2024-03-18','2024-03-19','low','resolved','general'),
(5037,40,'2024-06-25',NULL,'high','open','technical'),
(5038,42,'2024-04-08','2024-04-09','low','resolved','general'),
(5039,44,'2024-02-28','2024-03-01','high','resolved','technical'),
(5040,46,'2024-05-22',NULL,'medium','open','billing'),
(5041,48,'2024-03-05','2024-03-06','low','resolved','general'),
(5042,50,'2024-06-15','2024-06-17','medium','resolved','billing'),
(5043,41,'2024-04-18',NULL,'critical','open','technical'),
(5044,43,'2024-02-10','2024-02-11','low','resolved','general'),
(5045,45,'2024-05-28','2024-05-30','high','resolved','technical'),
(5046,47,'2024-03-15',NULL,'medium','open','billing'),
(5047,49,'2024-06-08','2024-06-10','medium','resolved','billing'),
(5048,38,'2024-04-25',NULL,'high','open','technical'),
(5049,32,'2024-02-22','2024-02-23','low','resolved','general'),
(5050,28,'2024-05-05','2024-05-07','medium','resolved','billing');

Why Apache Iceberg Matters Here

Every table you just created is stored as an Apache Iceberg table in Dremio's Open Catalog. This isn't just a storage choice. It directly affects the performance and reliability of your analytics.

Automated Performance Management. Dremio automatically maintains your Iceberg tables in the background. It compacts small files into larger, optimized ones (targeting 256 MB per file), rewrites manifest metadata for faster reads, clusters related records together, and vacuums obsolete data. You don't configure this. It happens automatically for every Iceberg table in the Open Catalog.

Results Cache. When you or the AI Agent run the same query more than once, Dremio returns the result from cache instead of re-executing the query. For a Customer 360 dashboard where certain views get hit repeatedly, this means sub-second responses without any additional configuration.

Autonomous Reflections. After your views start receiving queries, Dremio analyzes the access patterns over a 7-day window and automatically creates pre-computed materializations called Reflections. These are stored as Iceberg tables and the query optimizer substitutes them transparently. A query that used to scan millions of rows instead reads a pre-aggregated Reflection and returns in milliseconds. No DBA involvement required.

Iceberg vs. Federated: When to Use Which

In this tutorial, all source tables are Iceberg because they live in the Open Catalog. In production, the decision is more nuanced.

Keep data federated when real-time freshness matters. Your CRM's PostgreSQL database updates customer records throughout the day. If you replicate that data into Iceberg via an ETL pipeline, you introduce latency. Every pipeline has a schedule, and between runs your analytics are working with stale data. By querying PostgreSQL directly through Dremio's federation, you always see the latest record. You can still accelerate those federated queries by creating manual Reflections on the federated views. Dremio will pre-compute and cache the results, and you control the refresh schedule to balance performance against freshness.

Migrate data to Iceberg when you need Dremio's automated performance management. Iceberg tables in the Open Catalog get automatic compaction, manifest optimization, clustering, and vacuuming. They also qualify for Autonomous Reflections, where Dremio creates and manages Reflections without any manual setup. Historical data, aggregated reporting tables, and analytical datasets that don't need sub-minute freshness are strong candidates for Iceberg.

The practical approach: start with federation for all sources so you can query immediately. Then identify which datasets are queried most heavily or have the biggest performance gap, and migrate those to Iceberg tables in the Open Catalog. You get the best of both worlds: real-time access to operational data and automated optimization for analytical workloads.

Step 3: Build Bronze Views (Raw Layer)

Bronze views are the foundation of the medallion architecture. Their job is to create a clean, consistent interface over your raw source tables without changing the underlying data. Why bother? Because source systems use inconsistent conventions. Your CRM might store dates as DATE, your e-commerce system might use a different timezone, and your support tool might name its status column differently. Bronze views normalize these differences so that every downstream view works with a predictable schema.

In a production environment with real federated sources, Bronze views also serve as an abstraction layer. If you swap out your CRM vendor, you update one Bronze view instead of rewriting every Silver and Gold view that depends on it.

First, create the folders for each layer:

CREATE FOLDER IF NOT EXISTS customer360exp.bronze;
CREATE FOLDER IF NOT EXISTS customer360exp.silver;
CREATE FOLDER IF NOT EXISTS customer360exp.gold;

This view standardizes the customer table by casting the signup date to a TIMESTAMP type. This ensures consistent date handling when we join with orders and tickets downstream.

CREATE VIEW customer360exp.bronze.crm_customers AS
SELECT
  customer_id,
  first_name,
  last_name,
  email,
  segment,
  region,
  CAST(signup_date AS TIMESTAMP) AS signup_timestamp
FROM customer360exp.postgres.customers;

This view renames status to order_status to avoid ambiguity when we later join with the tickets table (which also has a status column). The date cast keeps timestamp types consistent.

CREATE VIEW customer360exp.bronze.ecomm_orders AS
SELECT
  order_id,
  customer_id,
  CAST(order_date AS TIMESTAMP) AS order_timestamp,
  total_amount,
  status AS order_status
FROM customer360exp.mysql.orders;

The tickets view renames status to ticket_status and casts both dates. The resolved_date can be NULL for open tickets, which we'll use later to calculate resolution time and identify unresolved issues.

CREATE VIEW customer360exp.bronze.support_tickets AS
SELECT
  ticket_id,
  customer_id,
  CAST(created_date AS TIMESTAMP) AS created_timestamp,
  CAST(resolved_date AS TIMESTAMP) AS resolved_timestamp,
  priority,
  status AS ticket_status,
  category
FROM customer360exp.mongo.tickets;

Step 4: Build Silver Views (Business Layer)

Silver views join data across sources and apply business logic. This is where the Customer 360 starts taking shape. Each Silver view answers a specific analytical question by combining data that previously lived in separate systems.

Customer Purchase Summary

This view joins customer profiles with their order history to answer: "How much has each customer spent, how frequently do they buy, and when did they last order?" The LEFT JOIN ensures customers with zero orders still appear in the results. Without this, you'd have blind spots in your Customer 360 for new customers who haven't purchased yet.

CREATE VIEW customer360exp.silver.customer_purchases AS
SELECT
  c.customer_id,
  c.first_name,
  c.last_name,
  c.segment,
  c.region,
  COUNT(o.order_id) AS total_orders,
  COALESCE(SUM(o.total_amount), 0) AS total_spent,
  COALESCE(AVG(o.total_amount), 0) AS avg_order_value,
  MAX(o.order_timestamp) AS last_order_date
FROM customer360exp.bronze.crm_customers c
LEFT JOIN customer360exp.bronze.ecomm_orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name, c.segment, c.region;

Customer Support Summary

This view calculates each customer's support footprint: total tickets, open tickets, high-priority escalations, and average resolution time. We use TIMESTAMPDIFF to compute resolution hours only for resolved tickets (where resolved_timestamp is not NULL). This metric is critical for the Gold layer's health score because a customer with high spend but multiple unresolved tickets is a churn risk.

CREATE VIEW customer360exp.silver.customer_support AS
SELECT
  c.customer_id,
  c.first_name,
  c.last_name,
  COUNT(t.ticket_id) AS total_tickets,
  SUM(CASE WHEN t.ticket_status = 'open' THEN 1 ELSE 0 END) AS open_tickets,
  SUM(CASE WHEN t.priority IN ('high', 'critical') THEN 1 ELSE 0 END) AS high_priority_tickets,
  AVG(CASE WHEN t.resolved_timestamp IS NOT NULL
    THEN TIMESTAMPDIFF(HOUR, t.created_timestamp, t.resolved_timestamp)
    ELSE NULL END) AS avg_resolution_hours
FROM customer360exp.bronze.crm_customers c
LEFT JOIN customer360exp.bronze.support_tickets t ON c.customer_id = t.customer_id
GROUP BY c.customer_id, c.first_name, c.last_name;

Step 5: Build Gold Views (Application Layer)

Gold views are the final, AI-ready datasets. They combine Silver views into the specific metrics that business users and the AI Agent will query directly. Each Gold view is designed to answer a category of business questions without requiring the user to understand the underlying joins or logic.

Customer Lifetime Value

This view combines purchase and support data into a single customer profile with a value_tier classification. The tier logic uses total spend thresholds: Platinum ($5,000+), Gold ($2,000+), Silver ($500+), and Bronze (under $500). This tiering lets sales and account teams prioritize outreach. The AI Agent can answer questions like "show me all Platinum customers in APAC" because the tier is pre-calculated in the view rather than requiring complex SQL at query time.

CREATE VIEW customer360exp.gold.customer_lifetime_value AS
SELECT
  p.customer_id,
  p.first_name || ' ' || p.last_name AS customer_name,
  p.segment,
  p.region,
  p.total_orders,
  p.total_spent,
  p.avg_order_value,
  p.last_order_date,
  s.total_tickets,
  s.open_tickets,
  CASE
    WHEN p.total_spent >= 5000 THEN 'Platinum'
    WHEN p.total_spent >= 2000 THEN 'Gold'
    WHEN p.total_spent >= 500 THEN 'Silver'
    ELSE 'Bronze'
  END AS value_tier
FROM customer360exp.silver.customer_purchases p
JOIN customer360exp.silver.customer_support s ON p.customer_id = s.customer_id;

Customer Health Score

This view classifies customers into health categories (At Risk, Needs Attention, Healthy, Stable) by combining spending behavior with support ticket patterns. A customer is "At Risk" when they have 2+ open tickets including at least one high-priority escalation, regardless of how much they spend. This is the view a customer success team would monitor daily to prevent churn. It answers: "Which valuable customers are having a bad experience right now?"

CREATE VIEW customer360exp.gold.customer_health_score AS
SELECT
  p.customer_id,
  p.first_name || ' ' || p.last_name AS customer_name,
  p.segment,
  p.region,
  p.total_spent,
  p.total_orders,
  s.open_tickets,
  s.high_priority_tickets,
  s.avg_resolution_hours,
  CASE
    WHEN s.open_tickets >= 2 AND s.high_priority_tickets >= 1 THEN 'At Risk'
    WHEN s.open_tickets >= 1 OR p.total_orders <= 1 THEN 'Needs Attention'
    WHEN p.total_spent >= 2000 AND s.open_tickets = 0 THEN 'Healthy'
    ELSE 'Stable'
  END AS health_status
FROM customer360exp.silver.customer_purchases p
JOIN customer360exp.silver.customer_support s ON p.customer_id = s.customer_id;

Step 6: Enable AI-Generated Wikis and Tags

The Gold views contain the right data, but the AI Agent needs to understand what each column and metric means in business terms. Dremio's AI Semantic Layer provides this context.

  1. Click Admin in the left sidebar, then go to Project Settings.
  2. Select the Preferences tab.
  3. Scroll to the AI section and enable Generate Wikis and Labels.
  4. Go to the Catalog and navigate to your Gold views under customer360exp.gold.
  5. Click the Edit button (pencil icon) next to the desired view.
  6. In the Details tab, find the Wiki section and click Generate Wiki. Do the same for the Tags section by clicking Generate Tags.
  7. Repeat for each Gold view.

Dremio's generative AI samples the view schema and data to produce descriptions like: "customer_lifetime_value: Contains one row per customer with their name, segment, region, total purchase history, support ticket counts, and a value tier classification (Platinum/Gold/Silver/Bronze) based on total spend."

Review the generated content and refine it. If you want to enhance the wiki with additional business context, copy the generated output into the AI Agent on the homepage and ask it to produce an improved version in a markdown code block. For example, you might ask the Agent to add details like "Platinum tier customers represent our top 5% by revenue and qualify for dedicated account management." Copy the Agent's output and paste it back into the wiki editor.

These wikis and labels are not decorative. They are the context that Dremio's AI Agent reads before generating SQL. Better metadata produces more accurate responses.

Step 7: Ask Questions with the AI Agent

Go to the Homepage and use the AI Agent chat box. Try these prompts:

"Who are the top 10 customers by total lifetime spend?"

The Agent will query customer360exp.gold.customer_lifetime_value, sort by total_spent, and return a ranked list. It uses the wiki context to understand that "lifetime spend" maps to the total_spent column.

"Show me a bar chart of average order value by customer segment."

The Agent generates the SQL, runs it, and renders a chart directly in the console. Enterprise customers will likely show higher average order values than SMB.

"Which customers are At Risk and have spent more than $3,000?"

This query uses the customer360exp.gold.customer_health_score view. The Agent understands "At Risk" is a value in the health_status column because the wiki describes the classification logic.

"Create a chart showing open support tickets by region and priority."

The Agent joins the necessary data and generates a grouped bar chart. This kind of cross-dimensional analysis would normally require a BI developer to build a dashboard. With the semantic layer in place, a business user can ask for it in plain English.

Next Steps

This tutorial used folders to simulate federated sources, but the same architecture works with real, live data:

  • Connect real sources. Add your PostgreSQL, MySQL, Snowflake, or S3 storage as federated sources. Dremio queries them in place without copying data.
  • Add access control. Apply Fine-Grained Access Control (FGAC) policies to mask PII like email addresses for non-admin users.
  • Connect BI tools. Use Arrow Flight SQL (JDBC/ODBC) to connect Tableau, Power BI, or Looker to your Gold views.
  • Scale with Autonomous Reflections. Once query patterns stabilize, Dremio automatically creates Reflections to accelerate the most common queries. You don't need to configure anything.

The Customer 360 view you built here is a working foundation. Replace the sample data with your own sources, and you have a governed, AI-ready analytics layer over your actual customer data.

Try Dremio Cloud free for 30 days and build your own Customer 360 in under an hour.

Try Dremio Cloud free for 30 days

Deploy agentic analytics directly on Apache Iceberg data with no pipelines and no added overhead.