PromptBase
Upgrade
Close icon
General
Home
Marketplace
Create
Hire
Login
Chat
Sell
Explore

Skill Details

Runtime
(claude-5-sonnet)
Example user message
[userMessage]: {{sql_query}}: SELECT u.id, u.first_name, u.last_name, COUNT(o.id) as total_orders, SUM(o.amount) as lifetime_value FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.created_at >= '2023-01-01' AND u.status = 'active' GROUP BY u.id, u.first_name, u.last_name HAVING SUM(o.amount) > 500 ORDER BY lifetime_value DESC LIMIT 50;
Example agent response
## πŸ“ Query Summary This query finds active users who signed up from 2023 onward, then ranks the top 50 by how much they've spent in total β€” but only includes users whose lifetime spending exceeds $500. ## πŸ” Step-by-Step Breakdown * **Data Retrieval:** Pulls each user's **id**, **first_name**, and **last_name** from the `users` table, plus two calculated columns: a count of their orders (**total_orders**) and the sum of their order amounts (**lifetime_value**). * **Relationships:** Uses a `LEFT JOIN` from `users` (aliased `u`) to `orders` (aliased `o`) on `u.id = o.user_id`. The `LEFT JOIN` means users with zero orders are still included, with `total_orders` and `lifetime_value` coming out as 0/NULL for them. * **Filtering & Grouping:** The `WHERE` clause first narrows things down to users created on or after **2023-01-01** with a **status** of `'active'`. Results are then grouped by **id**, **first_name**, and **last_name** (one row per user), and the `HAVING` clause filters those groups down to only users whose summed `amount` exceeds **500**. * **Sorting & Limits:** Rows are sorted by **lifetime_value** in descending order (highest spenders first), and the result set is capped at the top **50** rows. ## ⚑ Performance Notes & Bottlenecks * **Filter on `users.created_at` and `users.status`:** If there's no composite index covering `(status, created_at)`, this will force a full scan of the `users` table, especially costly if the table is large. * **`LEFT JOIN` + aggregate on `orders`:** Without an index on `orders.user_id`, this join can devolve into a scan-per-user pattern, which gets expensive as `orders` grows. * **`HAVING SUM(o.amount) > 500`:** This filter is applied *after* aggregation, meaning the database must compute the sum for every group before it can discard the low-value ones β€” there's no way to push this down to the row level, so it's inherently more expensive than a `WHERE` clause. * **`GROUP BY` on three columns:** Grouping by `id, first_name, last_name` is redundant since `id` is presumably the primary key. Grouping by extra non-key columns can, on some engines, prevent a more efficient index-based grouping strategy. * **No explicit filter on `orders`:** If `orders` has a `status` column (e.g., excluding refunded/cancelled orders), lifetime_value may be overcounting invalid orders β€” not a performance issue, but worth flagging. ## πŸ› οΈ Suggested Optimizations * **Add a composite index** on `users(status, created_at)` to speed up the initial filter. * **Ensure an index exists** on `orders(user_id)` (and ideally `orders(user_id, amount)` as a covering index) to make the join and aggregation more efficient. * **Simplify the `GROUP BY`** to just `u.id` if `first_name`/`last_name` are functionally dependent on `id` (MySQL allows this with `ONLY_FULL_GROUP_BY` off; Postgres requires them in the `SELECT` list but you can still group by the primary key alone in many cases). * **Consider precomputing lifetime value** (e.g., a materialized view or a denormalized `lifetime_value` column on `users`, updated via trigger or batch job) if this query runs frequently on a large `orders` table β€” recalculating sums on every request doesn't scale well. * **Double check the intent of `LEFT JOIN`:** since the `HAVING` clause requires `SUM(amount) > 500`, users with no orders are filtered out anyway β€” so unless you need to distinguish "zero orders" from "low-value orders" elsewhere, an `INNER JOIN` would be logically equivalent here and may let the optimizer choose a cheaper join strategy.
Add to Library
Instant accessInstant access
Usage rightsCommercial use
By downloading this skill, you agree to our terms of service
CLAUDE-5-SONNET
Tested icon
Guide icon
Stop wasting hours decoding legacy SQL queries. The SQL Query Explainer instantly translates complex, convoluted database queries into plain-English summaries. It automatically breaks down joins, subqueries, and filtering logic while providing actionable performance tuning notes to help you optimize slow execution times. Perfect for data analysts, junior developers, and product managers who need to understand, document, or improve SQL code fast.
...more
Added 2 weeks ago
Report
Browse Marketplace