SQL Pro
When to Use / When Not to Use
Use when:
- Writing or rewriting SQL queries: joins, CTEs, window functions, recursive queries
- Designing or normalizing a schema
- Interpreting an EXPLAIN plan for a slow query
- Migrating SQL between PostgreSQL, MySQL, and SQL Server dialects
Do not use when:
- The bottleneck is server-level config (use
database-optimizer)
- The issue is connection pool exhaustion (use
connection-pool-tuner)
Process
- Schema Analysis — Review table structure, existing indexes, query patterns
- Design — Draft set-based operations using CTEs, window functions, appropriate joins
- Version Check — Confirm target engine and version; flag any feature requiring a minimum version
- Optimize — Analyze execution plans; implement covering indexes; eliminate table scans
- Verify — Run
EXPLAIN ANALYZE and confirm no sequential scans on large tables; iterate until sub-100ms target is met
- Document — Provide query explanation, index rationale, performance metrics, and minimum version requirements
Output Template
For each SQL task, provide:
- Optimized query with inline comments
- Required indexes with rationale
- Execution plan analysis (key patterns found)
- Performance metrics (before/after)
- Platform-specific notes if applicable
- Minimum version requirements (e.g.,
PostgreSQL >= 10, MySQL >= 8.0)
What Claude Does / What You Do
| Claude |
You |
| Writes set-based query using CTEs or window functions |
Provide sample data or schema DDL |
| Recommends covering index strategy |
Run CREATE INDEX CONCURRENTLY in your environment |
| Reads EXPLAIN output and identifies plan patterns |
Provide actual EXPLAIN ANALYZE output |
| Flags dialect-specific syntax differences |
Test against your actual database version |
| Documents the before/after performance comparison |
Validate with production-scale data volumes |
Reference Guide
| Topic |
Reference |
Load When |
| Query Patterns |
references/query-patterns.md |
JOINs, CTEs, subqueries, recursive queries |
| Window Functions |
references/window-functions.md |
ROW_NUMBER, RANK, LAG/LEAD, analytics |
| Optimization |
references/optimization.md |
EXPLAIN plans, indexes, statistics |
| Database Design |
references/database-design.md |
Normalization, keys, constraints |
| Dialect Differences |
references/dialect-differences.md |
PostgreSQL vs MySQL vs SQL Server |
Quick-Reference Examples
CTE Pattern
WITH ranked_orders AS (
SELECT
customer_id,
order_id,
total_amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn
FROM orders
WHERE status = 'completed'
)
SELECT customer_id, order_id, total_amount
FROM ranked_orders
WHERE rn = 1; -- latest completed order per customer
Window Function Pattern
SELECT
department_id,
employee_id,
salary,
SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS running_payroll,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank
FROM employees;
Before / After Optimization
-- BEFORE: correlated subquery, one execution per row (slow)
SELECT order_id,
(SELECT SUM(quantity) FROM order_items oi WHERE oi.order_id = o.id) AS item_count
FROM orders o;
-- AFTER: single aggregation join (fast)
SELECT o.order_id, COALESCE(agg.item_count, 0) AS item_count
FROM orders o
LEFT JOIN (
SELECT order_id, SUM(quantity) AS item_count
FROM order_items
GROUP BY order_id
) agg ON agg.order_id = o.id;
Constraints
MUST DO:
- Analyze execution plans before recommending optimizations
- Use set-based operations over row-by-row processing
- Apply filtering early (before joins where possible)
- Use EXISTS over COUNT for existence checks
- Handle NULLs explicitly
MUST NOT DO:
- Use
SELECT * in production queries
- Use cursors when set-based operations work
- Implement solutions without considering data volume and cardinality
Related Skills
database-optimizer — server-level tuning after the query is optimized
connection-pool-tuner — pool sizing if slow queries are exhausting connections
spring-boot-engineer — for JPA query methods and @Query annotations
1---2name: sql-pro3description: Use when someone needs help writing or rewriting SQL — authoring complex joins, CTEs, window functions, or recursive queries — or designing a schema from scratch, normalizing an existing one, or migrating queries between database dialects.4license: MIT5---67# SQL Pro89## When to Use / When Not to Use1011**Use when:**12- Writing or rewriting SQL queries: joins, CTEs, window functions, recursive queries13- Designing or normalizing a schema14- Interpreting an EXPLAIN plan for a slow query15- Migrating SQL between PostgreSQL, MySQL, and SQL Server dialects1617**Do not use when:**18- The bottleneck is server-level config (use `database-optimizer`)19- The issue is connection pool exhaustion (use `connection-pool-tuner`)2021## Process22231. **Schema Analysis** — Review table structure, existing indexes, query patterns242. **Design** — Draft set-based operations using CTEs, window functions, appropriate joins253. **Version Check** — Confirm target engine and version; flag any feature requiring a minimum version264. **Optimize** — Analyze execution plans; implement covering indexes; eliminate table scans275. **Verify** — Run `EXPLAIN ANALYZE` and confirm no sequential scans on large tables; iterate until sub-100ms target is met286. **Document** — Provide query explanation, index rationale, performance metrics, and minimum version requirements2930## Output Template3132For each SQL task, provide:331. Optimized query with inline comments342. Required indexes with rationale353. Execution plan analysis (key patterns found)364. Performance metrics (before/after)375. Platform-specific notes if applicable386. Minimum version requirements (e.g., `PostgreSQL >= 10`, `MySQL >= 8.0`)3940## What Claude Does / What You Do4142| Claude | You |43|--------|-----|44| Writes set-based query using CTEs or window functions | Provide sample data or schema DDL |45| Recommends covering index strategy | Run `CREATE INDEX CONCURRENTLY` in your environment |46| Reads EXPLAIN output and identifies plan patterns | Provide actual EXPLAIN ANALYZE output |47| Flags dialect-specific syntax differences | Test against your actual database version |48| Documents the before/after performance comparison | Validate with production-scale data volumes |4950## Reference Guide5152| Topic | Reference | Load When |53|-------|-----------|-----------|54| Query Patterns | `references/query-patterns.md` | JOINs, CTEs, subqueries, recursive queries |55| Window Functions | `references/window-functions.md` | ROW_NUMBER, RANK, LAG/LEAD, analytics |56| Optimization | `references/optimization.md` | EXPLAIN plans, indexes, statistics |57| Database Design | `references/database-design.md` | Normalization, keys, constraints |58| Dialect Differences | `references/dialect-differences.md` | PostgreSQL vs MySQL vs SQL Server |5960## Quick-Reference Examples6162### CTE Pattern63```sql64WITH ranked_orders AS (65 SELECT66 customer_id,67 order_id,68 total_amount,69 ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn70 FROM orders71 WHERE status = 'completed'72)73SELECT customer_id, order_id, total_amount74FROM ranked_orders75WHERE rn = 1; -- latest completed order per customer76```7778### Window Function Pattern79```sql80SELECT81 department_id,82 employee_id,83 salary,84 SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS running_payroll,85 RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank86FROM employees;87```8889### Before / After Optimization90```sql91-- BEFORE: correlated subquery, one execution per row (slow)92SELECT order_id,93 (SELECT SUM(quantity) FROM order_items oi WHERE oi.order_id = o.id) AS item_count94FROM orders o;9596-- AFTER: single aggregation join (fast)97SELECT o.order_id, COALESCE(agg.item_count, 0) AS item_count98FROM orders o99LEFT JOIN (100 SELECT order_id, SUM(quantity) AS item_count101 FROM order_items102 GROUP BY order_id103) agg ON agg.order_id = o.id;104```105106## Constraints107108**MUST DO:**109- Analyze execution plans before recommending optimizations110- Use set-based operations over row-by-row processing111- Apply filtering early (before joins where possible)112- Use EXISTS over COUNT for existence checks113- Handle NULLs explicitly114115**MUST NOT DO:**116- Use `SELECT *` in production queries117- Use cursors when set-based operations work118- Implement solutions without considering data volume and cardinality119120## Related Skills121122- `database-optimizer` — server-level tuning after the query is optimized123- `connection-pool-tuner` — pool sizing if slow queries are exhausting connections124- `spring-boot-engineer` — for JPA query methods and `@Query` annotations