Databricks SQL (DBSQL) - Advanced Features
Quick Reference
| Feature |
Key Syntax |
Since |
Reference |
| SQL Scripting |
BEGIN...END, DECLARE, IF/WHILE/FOR |
DBR 16.3+ |
references/sql-scripting.md |
| Stored Procedures |
CREATE PROCEDURE, CALL |
DBR 17.0+ |
references/sql-scripting.md |
| Recursive CTEs |
WITH RECURSIVE |
DBR 17.0+ |
references/sql-scripting.md |
| Transactions |
BEGIN ATOMIC...END |
Preview |
references/sql-scripting.md |
| Materialized Views |
CREATE MATERIALIZED VIEW |
Pro/Serverless |
references/materialized-views-pipes.md |
| Temp Tables |
CREATE TEMPORARY TABLE |
All |
references/materialized-views-pipes.md |
| Pipe Syntax |
|> operator |
DBR 16.1+ |
references/materialized-views-pipes.md |
| Geospatial (H3) |
h3_longlatash3(), h3_polyfillash3() |
DBR 11.2+ |
references/geospatial-collations.md |
| Geospatial (ST) |
ST_Point(), ST_Contains(), 80+ funcs |
DBR 16.0+ |
references/geospatial-collations.md |
| Collations |
COLLATE, UTF8_LCASE, locale-aware |
DBR 16.1+ |
references/geospatial-collations.md |
| AI Functions |
ai_query(), ai_classify(), 11+ funcs |
DBR 15.1+ |
references/ai-functions.md |
| http_request |
http_request(conn, ...) |
Pro/Serverless |
references/ai-functions.md |
| remote_query |
SELECT * FROM remote_query(...) |
Pro/Serverless |
references/ai-functions.md |
| read_files |
SELECT * FROM read_files(...) |
All |
references/ai-functions.md |
| Data Modeling |
Star schema, Liquid Clustering |
All |
references/best-practices.md |
Common Patterns
SQL Scripting - Procedural ETL
BEGIN
DECLARE v_count INT;
DECLARE v_status STRING DEFAULT 'pending';
SET v_count = (SELECT COUNT(*) FROM catalog.schema.raw_orders WHERE status = 'new');
IF v_count > 0 THEN
INSERT INTO catalog.schema.processed_orders
SELECT *, current_timestamp() AS processed_at
FROM catalog.schema.raw_orders
WHERE status = 'new';
SET v_status = 'completed';
ELSE
SET v_status = 'skipped';
END IF;
SELECT v_status AS result, v_count AS rows_processed;
END
Stored Procedure with Error Handling
CREATE OR REPLACE PROCEDURE catalog.schema.upsert_customers(
IN p_source STRING,
OUT p_rows_affected INT
)
LANGUAGE SQL
SQL SECURITY INVOKER
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET p_rows_affected = -1;
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = concat('Upsert failed for source: ', p_source);
END;
MERGE INTO catalog.schema.dim_customer AS t
USING (SELECT * FROM identifier(p_source)) AS s
ON t.customer_id = s.customer_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;
SET p_rows_affected = (SELECT COUNT(*) FROM identifier(p_source));
END;
-- Invoke:
CALL catalog.schema.upsert_customers('catalog.schema.staging_customers', ?);
Materialized View with Scheduled Refresh
CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.daily_revenue
CLUSTER BY (order_date)
SCHEDULE EVERY 1 HOUR
COMMENT 'Hourly-refreshed daily revenue by region'
AS SELECT
order_date,
region,
SUM(amount) AS total_revenue,
COUNT(DISTINCT customer_id) AS unique_customers
FROM catalog.schema.fact_orders
JOIN catalog.schema.dim_store USING (store_id)
GROUP BY order_date, region;
Pipe Syntax - Readable Transformations
-- Traditional SQL rewritten with pipe syntax
FROM catalog.schema.fact_orders
|> WHERE order_date >= current_date() - INTERVAL 30 DAYS
|> AGGREGATE SUM(amount) AS total, COUNT(*) AS cnt GROUP BY region, product_category
|> WHERE total > 10000
|> ORDER BY total DESC
|> LIMIT 20;
AI Functions - Enrich Data with LLMs
-- Classify support tickets
SELECT
ticket_id,
description,
ai_classify(description, ARRAY('billing', 'technical', 'account', 'feature_request')) AS category,
ai_analyze_sentiment(description) AS sentiment
FROM catalog.schema.support_tickets
LIMIT 100;
-- Extract entities from text
SELECT
doc_id,
ai_extract(content, ARRAY('person_name', 'company', 'dollar_amount')) AS entities
FROM catalog.schema.contracts;
-- General-purpose AI query with structured output
SELECT ai_query(
'databricks-meta-llama-3-3-70b-instruct',
concat('Summarize this customer feedback in JSON with keys: topic, sentiment, action_items. Feedback: ', feedback),
returnType => 'STRUCT<topic STRING, sentiment STRING, action_items ARRAY<STRING>>'
) AS analysis
FROM catalog.schema.customer_feedback
LIMIT 50;
Geospatial - Proximity Search with H3
-- Find stores within 5km of each customer using H3 indexing
WITH customer_h3 AS (
SELECT *, h3_longlatash3(longitude, latitude, 7) AS h3_cell
FROM catalog.schema.customers
),
store_h3 AS (
SELECT *, h3_longlatash3(longitude, latitude, 7) AS h3_cell
FROM catalog.schema.stores
)
SELECT
c.customer_id,
s.store_id,
ST_Distance(
ST_Point(c.longitude, c.latitude),
ST_Point(s.longitude, s.latitude)
) AS distance_m
FROM customer_h3 c
JOIN store_h3 s ON h3_ischildof(c.h3_cell, h3_toparent(s.h3_cell, 5))
WHERE ST_Distance(
ST_Point(c.longitude, c.latitude),
ST_Point(s.longitude, s.latitude)
) < 5000;
Collation - Case-Insensitive Search
-- Create table with case-insensitive collation
CREATE TABLE catalog.schema.products (
product_id BIGINT GENERATED ALWAYS AS IDENTITY,
name STRING COLLATE UTF8_LCASE,
category STRING COLLATE UTF8_LCASE,
price DECIMAL(10, 2)
);
-- Queries automatically case-insensitive (no LOWER() needed)
SELECT * FROM catalog.schema.products
WHERE name = 'MacBook Pro'; -- matches 'macbook pro', 'MACBOOK PRO', etc.
http_request - Call External APIs
-- Set up connection first (one-time)
CREATE CONNECTION my_api_conn
TYPE HTTP
OPTIONS (host 'https://api.example.com', bearer_token secret('scope', 'token'));
-- Call API from SQL
SELECT
order_id,
http_request(
conn => 'my_api_conn',
method => 'POST',
path => '/v1/validate',
json => to_json(named_struct('order_id', order_id, 'amount', amount))
).text AS api_response
FROM catalog.schema.orders
WHERE needs_validation = true;
read_files - Ingest Raw Files
-- Read JSON files from a Volume with schema hints
SELECT *
FROM read_files(
'/Volumes/catalog/schema/raw/events/',
format => 'json',
schemaHints => 'event_id STRING, timestamp TIMESTAMP, payload MAP<STRING, STRING>',
pathGlobFilter => '*.json',
recursiveFileLookup => true
);
-- Read CSV with options
SELECT *
FROM read_files(
'/Volumes/catalog/schema/raw/sales/',
format => 'csv',
header => true,
delimiter => '|',
dateFormat => 'yyyy-MM-dd',
schema => 'sale_id INT, sale_date DATE, amount DECIMAL(10,2), store STRING'
);
Recursive CTE - Hierarchy Traversal
WITH RECURSIVE org_chart AS (
-- Anchor: top-level managers
SELECT employee_id, name, manager_id, 0 AS depth, ARRAY(name) AS path
FROM catalog.schema.employees
WHERE manager_id IS NULL
UNION ALL
-- Recursive: direct reports
SELECT e.employee_id, e.name, e.manager_id, o.depth + 1, array_append(o.path, e.name)
FROM catalog.schema.employees e
JOIN org_chart o ON e.manager_id = o.employee_id
WHERE o.depth < 10 -- safety limit
)
SELECT * FROM org_chart ORDER BY depth, name;
remote_query - Federated Queries
-- Query PostgreSQL via Lakehouse Federation
SELECT *
FROM remote_query(
'my_postgres_connection',
database => 'my_database',
query => 'SELECT customer_id, email, created_at FROM customers WHERE active = true'
);
Reference Files
Load these for detailed syntax, full parameter lists, and advanced patterns:
| File |
Contents |
When to Read |
| references/sql-scripting.md |
SQL Scripting, Stored Procedures, Recursive CTEs, Transactions |
User needs procedural SQL, error handling, loops, dynamic SQL |
| references/materialized-views-pipes.md |
Materialized Views, Temp Tables/Views, Pipe Syntax |
User needs MVs, refresh scheduling, temp objects, pipe operator |
| references/geospatial-collations.md |
39 H3 functions, 80+ ST functions, Collation types and hierarchy |
User needs spatial analysis, H3 indexing, case/accent handling |
| references/ai-functions.md |
13 AI functions, http_request, remote_query, read_files (all options) |
User needs AI enrichment, API calls, federation, file ingestion |
| references/best-practices.md |
Data modeling, performance, Liquid Clustering, anti-patterns |
User needs architecture guidance, optimization, or modeling advice |
Key Guidelines
- Always use Serverless SQL warehouses for AI functions, MVs, and http_request
- Use
LIMIT during development with AI functions to control costs
- Prefer Liquid Clustering over partitioning for new tables (1-4 keys max)
- Use
CLUSTER BY AUTO when unsure about clustering keys
- Star schema in Gold layer for BI; OBT acceptable in Silver
- Define PK/FK constraints on dimensional models for query optimization
- Use
COLLATE UTF8_LCASE for user-facing string columns that need case-insensitive search
- Test SQL via CLI (
databricks experimental aitools tools query) or notebooks before deploying. If --warehouse is rejected on your CLI version, set DATABRICKS_WAREHOUSE_ID in the environment instead.
1---2name: databricks-dbsql3description: Databricks SQL (DBSQL) advanced features and SQL warehouse capabilities. This skill MUST be invoked when the user mentions: "DBSQL", "Databricks SQL", "SQL warehouse", "SQL scripting", "stored procedure", "CALL procedure", "materialized view", "CREATE MATERIALIZED VIEW", "pipe syntax", "|>", "geospatial", "H3", "ST_", "spatial SQL", "collation", "COLLATE", "ai_query", "ai_classify", "ai_extract", "ai_gen", "AI function", "http_request", "remote_query", "read_files", "Lakehouse Federation", "recursive CTE", "WITH RECURSIVE", "multi-statement transaction", "temp table", "temporary view", "pipe operator". SHOULD also invoke when the user asks about SQL best practices, data modeling patterns, or advanced SQL features on Databricks.4---5
6# Databricks SQL (DBSQL) - Advanced Features
7
8## Quick Reference
9
10| Feature | Key Syntax | Since | Reference |
11|---------|-----------|-------|-----------|
12| SQL Scripting | `BEGIN...END`, `DECLARE`, `IF/WHILE/FOR` | DBR 16.3+ | [references/sql-scripting.md](references/sql-scripting.md) |
13| Stored Procedures | `CREATE PROCEDURE`, `CALL` | DBR 17.0+ | [references/sql-scripting.md](references/sql-scripting.md) |
14| Recursive CTEs | `WITH RECURSIVE` | DBR 17.0+ | [references/sql-scripting.md](references/sql-scripting.md) |
15| Transactions | `BEGIN ATOMIC...END` | Preview | [references/sql-scripting.md](references/sql-scripting.md) |
16| Materialized Views | `CREATE MATERIALIZED VIEW` | Pro/Serverless | [references/materialized-views-pipes.md](references/materialized-views-pipes.md) |
17| Temp Tables | `CREATE TEMPORARY TABLE` | All | [references/materialized-views-pipes.md](references/materialized-views-pipes.md) |
18| Pipe Syntax | `\|>` operator | DBR 16.1+ | [references/materialized-views-pipes.md](references/materialized-views-pipes.md) |
19| Geospatial (H3) | `h3_longlatash3()`, `h3_polyfillash3()` | DBR 11.2+ | [references/geospatial-collations.md](references/geospatial-collations.md) |
20| Geospatial (ST) | `ST_Point()`, `ST_Contains()`, 80+ funcs | DBR 16.0+ | [references/geospatial-collations.md](references/geospatial-collations.md) |
21| Collations | `COLLATE`, `UTF8_LCASE`, locale-aware | DBR 16.1+ | [references/geospatial-collations.md](references/geospatial-collations.md) |
22| AI Functions | `ai_query()`, `ai_classify()`, 11+ funcs | DBR 15.1+ | [references/ai-functions.md](references/ai-functions.md) |
23| http_request | `http_request(conn, ...)` | Pro/Serverless | [references/ai-functions.md](references/ai-functions.md) |
24| remote_query | `SELECT * FROM remote_query(...)` | Pro/Serverless | [references/ai-functions.md](references/ai-functions.md) |
25| read_files | `SELECT * FROM read_files(...)` | All | [references/ai-functions.md](references/ai-functions.md) |
26| Data Modeling | Star schema, Liquid Clustering | All | [references/best-practices.md](references/best-practices.md) |
27
28---
29
30## Common Patterns
31
32### SQL Scripting - Procedural ETL
33
34```sql
35BEGIN
36 DECLARE v_count INT;
37 DECLARE v_status STRING DEFAULT 'pending';
38
39 SET v_count = (SELECT COUNT(*) FROM catalog.schema.raw_orders WHERE status = 'new');
40
41 IF v_count > 0 THEN
42 INSERT INTO catalog.schema.processed_orders
43 SELECT *, current_timestamp() AS processed_at
44 FROM catalog.schema.raw_orders
45 WHERE status = 'new';
46
47 SET v_status = 'completed';
48 ELSE
49 SET v_status = 'skipped';
50 END IF;
51
52 SELECT v_status AS result, v_count AS rows_processed;
53END
54```
55
56### Stored Procedure with Error Handling
57
58```sql
59CREATE OR REPLACE PROCEDURE catalog.schema.upsert_customers(
60 IN p_source STRING,
61 OUT p_rows_affected INT
62)
63LANGUAGE SQL
64SQL SECURITY INVOKER
65BEGIN
66 DECLARE EXIT HANDLER FOR SQLEXCEPTION
67 BEGIN
68 SET p_rows_affected = -1;
69 SIGNAL SQLSTATE '45000'
70 SET MESSAGE_TEXT = concat('Upsert failed for source: ', p_source);
71 END;
72
73 MERGE INTO catalog.schema.dim_customer AS t
74 USING (SELECT * FROM identifier(p_source)) AS s
75 ON t.customer_id = s.customer_id
76 WHEN MATCHED THEN UPDATE SET *
77 WHEN NOT MATCHED THEN INSERT *;
78
79 SET p_rows_affected = (SELECT COUNT(*) FROM identifier(p_source));
80END;
81
82-- Invoke:
83CALL catalog.schema.upsert_customers('catalog.schema.staging_customers', ?);
84```
85
86### Materialized View with Scheduled Refresh
87
88```sql
89CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.daily_revenue
90 CLUSTER BY (order_date)
91 SCHEDULE EVERY 1 HOUR
92 COMMENT 'Hourly-refreshed daily revenue by region'
93AS SELECT
94 order_date,
95 region,
96 SUM(amount) AS total_revenue,
97 COUNT(DISTINCT customer_id) AS unique_customers
98FROM catalog.schema.fact_orders
99JOIN catalog.schema.dim_store USING (store_id)
100GROUP BY order_date, region;
101```
102
103### Pipe Syntax - Readable Transformations
104
105```sql
106-- Traditional SQL rewritten with pipe syntax
107FROM catalog.schema.fact_orders
108 |> WHERE order_date >= current_date() - INTERVAL 30 DAYS
109 |> AGGREGATE SUM(amount) AS total, COUNT(*) AS cnt GROUP BY region, product_category
110 |> WHERE total > 10000
111 |> ORDER BY total DESC
112 |> LIMIT 20;
113```
114
115### AI Functions - Enrich Data with LLMs
116
117```sql
118-- Classify support tickets
119SELECT
120 ticket_id,
121 description,
122 ai_classify(description, ARRAY('billing', 'technical', 'account', 'feature_request')) AS category,
123 ai_analyze_sentiment(description) AS sentiment
124FROM catalog.schema.support_tickets
125LIMIT 100;
126
127-- Extract entities from text
128SELECT
129 doc_id,
130 ai_extract(content, ARRAY('person_name', 'company', 'dollar_amount')) AS entities
131FROM catalog.schema.contracts;
132
133-- General-purpose AI query with structured output
134SELECT ai_query(
135 'databricks-meta-llama-3-3-70b-instruct',
136 concat('Summarize this customer feedback in JSON with keys: topic, sentiment, action_items. Feedback: ', feedback),
137 returnType => 'STRUCT<topic STRING, sentiment STRING, action_items ARRAY<STRING>>'
138) AS analysis
139FROM catalog.schema.customer_feedback
140LIMIT 50;
141```
142
143### Geospatial - Proximity Search with H3
144
145```sql
146-- Find stores within 5km of each customer using H3 indexing
147WITH customer_h3 AS (
148 SELECT *, h3_longlatash3(longitude, latitude, 7) AS h3_cell
149 FROM catalog.schema.customers
150),
151store_h3 AS (
152 SELECT *, h3_longlatash3(longitude, latitude, 7) AS h3_cell
153 FROM catalog.schema.stores
154)
155SELECT
156 c.customer_id,
157 s.store_id,
158 ST_Distance(
159 ST_Point(c.longitude, c.latitude),
160 ST_Point(s.longitude, s.latitude)
161 ) AS distance_m
162FROM customer_h3 c
163JOIN store_h3 s ON h3_ischildof(c.h3_cell, h3_toparent(s.h3_cell, 5))
164WHERE ST_Distance(
165 ST_Point(c.longitude, c.latitude),
166 ST_Point(s.longitude, s.latitude)
167) < 5000;
168```
169
170### Collation - Case-Insensitive Search
171
172```sql
173-- Create table with case-insensitive collation
174CREATE TABLE catalog.schema.products (
175 product_id BIGINT GENERATED ALWAYS AS IDENTITY,
176 name STRING COLLATE UTF8_LCASE,
177 category STRING COLLATE UTF8_LCASE,
178 price DECIMAL(10, 2)
179);
180
181-- Queries automatically case-insensitive (no LOWER() needed)
182SELECT * FROM catalog.schema.products
183WHERE name = 'MacBook Pro'; -- matches 'macbook pro', 'MACBOOK PRO', etc.
184```
185
186### http_request - Call External APIs
187
188```sql
189-- Set up connection first (one-time)
190CREATE CONNECTION my_api_conn
191 TYPE HTTP
192 OPTIONS (host 'https://api.example.com', bearer_token secret('scope', 'token'));
193
194-- Call API from SQL
195SELECT
196 order_id,
197 http_request(
198 conn => 'my_api_conn',
199 method => 'POST',
200 path => '/v1/validate',
201 json => to_json(named_struct('order_id', order_id, 'amount', amount))
202 ).text AS api_response
203FROM catalog.schema.orders
204WHERE needs_validation = true;
205```
206
207### read_files - Ingest Raw Files
208
209```sql
210-- Read JSON files from a Volume with schema hints
211SELECT *
212FROM read_files(
213 '/Volumes/catalog/schema/raw/events/',
214 format => 'json',
215 schemaHints => 'event_id STRING, timestamp TIMESTAMP, payload MAP<STRING, STRING>',
216 pathGlobFilter => '*.json',
217 recursiveFileLookup => true
218);
219
220-- Read CSV with options
221SELECT *
222FROM read_files(
223 '/Volumes/catalog/schema/raw/sales/',
224 format => 'csv',
225 header => true,
226 delimiter => '|',
227 dateFormat => 'yyyy-MM-dd',
228 schema => 'sale_id INT, sale_date DATE, amount DECIMAL(10,2), store STRING'
229);
230```
231
232### Recursive CTE - Hierarchy Traversal
233
234```sql
235WITH RECURSIVE org_chart AS (
236 -- Anchor: top-level managers
237 SELECT employee_id, name, manager_id, 0 AS depth, ARRAY(name) AS path
238 FROM catalog.schema.employees
239 WHERE manager_id IS NULL
240
241 UNION ALL
242
243 -- Recursive: direct reports
244 SELECT e.employee_id, e.name, e.manager_id, o.depth + 1, array_append(o.path, e.name)
245 FROM catalog.schema.employees e
246 JOIN org_chart o ON e.manager_id = o.employee_id
247 WHERE o.depth < 10 -- safety limit
248)
249SELECT * FROM org_chart ORDER BY depth, name;
250```
251
252### remote_query - Federated Queries
253
254```sql
255-- Query PostgreSQL via Lakehouse Federation
256SELECT *
257FROM remote_query(
258 'my_postgres_connection',
259 database => 'my_database',
260 query => 'SELECT customer_id, email, created_at FROM customers WHERE active = true'
261);
262```
263
264---
265
266## Reference Files
267
268Load these for detailed syntax, full parameter lists, and advanced patterns:
269
270| File | Contents | When to Read |
271|------|----------|--------------|
272| [references/sql-scripting.md](references/sql-scripting.md) | SQL Scripting, Stored Procedures, Recursive CTEs, Transactions | User needs procedural SQL, error handling, loops, dynamic SQL |
273| [references/materialized-views-pipes.md](references/materialized-views-pipes.md) | Materialized Views, Temp Tables/Views, Pipe Syntax | User needs MVs, refresh scheduling, temp objects, pipe operator |
274| [references/geospatial-collations.md](references/geospatial-collations.md) | 39 H3 functions, 80+ ST functions, Collation types and hierarchy | User needs spatial analysis, H3 indexing, case/accent handling |
275| [references/ai-functions.md](references/ai-functions.md) | 13 AI functions, http_request, remote_query, read_files (all options) | User needs AI enrichment, API calls, federation, file ingestion |
276| [references/best-practices.md](references/best-practices.md) | Data modeling, performance, Liquid Clustering, anti-patterns | User needs architecture guidance, optimization, or modeling advice |
277
278---
279
280## Key Guidelines
281
282- **Always use Serverless SQL warehouses** for AI functions, MVs, and http_request
283- **Use `LIMIT` during development** with AI functions to control costs
284- **Prefer Liquid Clustering over partitioning** for new tables (1-4 keys max)
285- **Use `CLUSTER BY AUTO`** when unsure about clustering keys
286- **Star schema in Gold layer** for BI; OBT acceptable in Silver
287- **Define PK/FK constraints** on dimensional models for query optimization
288- **Use `COLLATE UTF8_LCASE`** for user-facing string columns that need case-insensitive search
289- **Test SQL via CLI** (`databricks experimental aitools tools query`) or notebooks before deploying. If `--warehouse` is rejected on your CLI version, set `DATABRICKS_WAREHOUSE_ID` in the environment instead.