[{"category": "Basics", "name": "Peek at a table", "description": "SELECT with LIMIT — always bound your exploratory queries", "query": "SELECT * FROM orders LIMIT 10"}, {"category": "Basics", "name": "Sorting", "description": "Largest completed orders first", "query": "SELECT order_id, customer_id, total_amount, order_date\nFROM orders\nWHERE status = 'completed'\nORDER BY total_amount DESC\nLIMIT 15"}, {"category": "Basics", "name": "Distinct values", "description": "What statuses exist, and how many of each?", "query": "SELECT DISTINCT status FROM orders ORDER BY status"}, {"category": "Basics", "name": "Computed columns", "description": "Margin and margin % from price and cost", "query": "SELECT name, category, price, cost,\n ROUND(price - cost, 2) AS margin,\n ROUND(100.0 * (price - cost) / price, 1) AS margin_pct\nFROM products\nORDER BY margin_pct DESC\nLIMIT 15"}, {"category": "Basics", "name": "Row counts per table", "description": "UNION ALL to stack per-table counts", "query": "SELECT 'customers' AS table_name, COUNT(*) AS rows FROM customers\nUNION ALL SELECT 'products', COUNT(*) FROM products\nUNION ALL SELECT 'orders', COUNT(*) FROM orders\nUNION ALL SELECT 'order_items', COUNT(*) FROM order_items"}, {"category": "Basics", "name": "Random sample", "description": "DuckDB's USING SAMPLE for quick data inspection", "query": "SELECT * FROM customers USING SAMPLE 10 ROWS"}, {"category": "Filtering", "name": "Combining conditions", "description": "AND/OR with explicit parentheses", "query": "SELECT order_id, total_amount, payment_method\nFROM orders\nWHERE status = 'completed'\n AND (payment_method = 'credit_card' OR payment_method = 'paypal')\n AND total_amount > 400\nORDER BY total_amount DESC\nLIMIT 15"}, {"category": "Filtering", "name": "IN lists", "description": "Membership tests instead of chained ORs", "query": "SELECT country, COUNT(*) AS customers\nFROM customers\nWHERE country IN ('UK', 'Germany', 'France')\nGROUP BY country\nORDER BY customers DESC"}, {"category": "Filtering", "name": "Date ranges", "description": "BETWEEN on timestamps — Q1 2024 orders", "query": "SELECT COUNT(*) AS q1_orders, ROUND(SUM(total_amount), 2) AS q1_revenue\nFROM orders\nWHERE order_date BETWEEN '2024-01-01' AND '2024-03-31 23:59:59'\n AND status = 'completed'"}, {"category": "Filtering", "name": "Pattern matching", "description": "LIKE with wildcards", "query": "SELECT email, name\nFROM customers\nWHERE email LIKE 'customer1__@%'\nORDER BY email\nLIMIT 15"}, {"category": "Filtering", "name": "Anti-join: customers with no orders", "description": "NOT EXISTS — the reliable way to find missing relationships", "query": "SELECT c.customer_id, c.name, c.country\nFROM customers c\nWHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id)\nORDER BY c.customer_id\nLIMIT 20"}, {"category": "Filtering", "name": "CASE bucketing", "description": "Label rows into bands, then count the bands", "query": "SELECT CASE\n WHEN total_amount < 100 THEN 'small'\n WHEN total_amount < 300 THEN 'medium'\n ELSE 'large'\n END AS order_size,\n COUNT(*) AS orders,\n ROUND(AVG(total_amount), 2) AS avg_amount\nFROM orders\nGROUP BY 1\nORDER BY avg_amount"}, {"category": "Joins", "name": "Inner join", "description": "Order lines with product names and categories", "query": "SELECT oi.order_id, p.name, p.category, oi.quantity, oi.unit_price\nFROM order_items oi\nJOIN products p ON p.product_id = oi.product_id\nORDER BY oi.order_id\nLIMIT 15"}, {"category": "Joins", "name": "Left join with zero-fill", "description": "Every customer, including the ones who never ordered", "query": "SELECT c.customer_id, c.name,\n COUNT(o.order_id) AS orders,\n COALESCE(ROUND(SUM(o.total_amount), 2), 0) AS total_spend\nFROM customers c\nLEFT JOIN orders o ON o.customer_id = c.customer_id AND o.status = 'completed'\nGROUP BY 1, 2\nORDER BY total_spend ASC\nLIMIT 15"}, {"category": "Joins", "name": "Four-table join", "description": "Country × category revenue through the full schema", "query": "SELECT c.country, p.category,\n ROUND(SUM(oi.quantity * oi.unit_price), 2) AS revenue\nFROM customers c\nJOIN orders o ON o.customer_id = c.customer_id\nJOIN order_items oi ON oi.order_id = o.order_id\nJOIN products p ON p.product_id = oi.product_id\nWHERE o.status = 'completed'\nGROUP BY 1, 2\nORDER BY revenue DESC\nLIMIT 20"}, {"category": "Joins", "name": "Self join", "description": "Similar-priced products within the same category", "query": "SELECT a.category, a.name AS product_a, b.name AS product_b,\n a.price AS price_a, b.price AS price_b\nFROM products a\nJOIN products b ON a.category = b.category\n AND a.product_id < b.product_id\n AND ABS(a.price - b.price) < 5\nORDER BY a.category, a.price\nLIMIT 15"}, {"category": "Joins", "name": "Semi join (EXISTS)", "description": "Customers who have at least one refunded order", "query": "SELECT c.customer_id, c.name, c.segment\nFROM customers c\nWHERE EXISTS (\n SELECT 1 FROM orders o\n WHERE o.customer_id = c.customer_id AND o.status = 'refunded'\n)\nORDER BY c.customer_id\nLIMIT 20"}, {"category": "Joins", "name": "Date spine", "description": "generate_series + LEFT JOIN so days without orders still appear", "query": "SELECT spine.day, COALESCE(ROUND(SUM(o.total_amount), 2), 0) AS revenue\nFROM generate_series(DATE '2024-01-01', DATE '2024-01-14', INTERVAL 1 DAY) AS spine(day)\nLEFT JOIN orders o\n ON CAST(o.order_date AS DATE) = spine.day AND o.status = 'completed'\nGROUP BY spine.day\nORDER BY spine.day"}, {"category": "Joins", "name": "Join vs join-with-filter", "description": "Filter inside the ON clause keeps unmatched rows", "query": "SELECT c.segment,\n COUNT(DISTINCT c.customer_id) AS all_customers,\n COUNT(DISTINCT o.customer_id) AS crypto_payers\nFROM customers c\nLEFT JOIN orders o ON o.customer_id = c.customer_id AND o.payment_method = 'crypto'\nGROUP BY 1\nORDER BY all_customers DESC"}, {"category": "Aggregation", "name": "GROUP BY + HAVING", "description": "HAVING filters groups after aggregation", "query": "SELECT country, COUNT(*) AS customers\nFROM customers\nGROUP BY country\nHAVING COUNT(*) > 100\nORDER BY customers DESC"}, {"category": "Aggregation", "name": "The full aggregate set", "description": "COUNT/SUM/AVG/MIN/MAX in one pass", "query": "SELECT status,\n COUNT(*) AS orders,\n ROUND(SUM(total_amount), 2) AS revenue,\n ROUND(AVG(total_amount), 2) AS avg_value,\n MIN(total_amount) AS smallest,\n MAX(total_amount) AS largest\nFROM orders\nGROUP BY status\nORDER BY revenue DESC"}, {"category": "Aggregation", "name": "Conditional aggregation (FILTER)", "description": "Pivot statuses into columns without a PIVOT clause", "query": "SELECT payment_method,\n COUNT(*) FILTER (WHERE status = 'completed') AS completed,\n COUNT(*) FILTER (WHERE status = 'cancelled') AS cancelled,\n COUNT(*) FILTER (WHERE status = 'refunded') AS refunded\nFROM orders\nGROUP BY 1\nORDER BY completed DESC"}, {"category": "Aggregation", "name": "ROLLUP subtotals", "description": "Per-group rows plus subtotal and grand-total rows", "query": "SELECT c.country, c.segment, ROUND(SUM(o.total_amount), 2) AS revenue\nFROM customers c\nJOIN orders o ON o.customer_id = c.customer_id\nWHERE o.status = 'completed'\nGROUP BY ROLLUP (c.country, c.segment)\nORDER BY c.country NULLS LAST, c.segment NULLS LAST"}, {"category": "Aggregation", "name": "Median and percentiles", "description": "PERCENTILE_CONT for distribution shape, not just averages", "query": "SELECT status,\n ROUND(AVG(total_amount), 2) AS mean,\n PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY total_amount) AS median,\n PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY total_amount) AS p90\nFROM orders\nGROUP BY status"}, {"category": "Aggregation", "name": "String aggregation", "description": "STRING_AGG collapses a group into one readable cell", "query": "SELECT oi.order_id,\n STRING_AGG(DISTINCT p.category, ', ' ORDER BY p.category) AS categories_in_order\nFROM order_items oi\nJOIN products p ON p.product_id = oi.product_id\nGROUP BY oi.order_id\nORDER BY oi.order_id\nLIMIT 12"}, {"category": "Aggregation", "name": "Distinct counts", "description": "COUNT(DISTINCT ...) — unique buyers per payment method", "query": "SELECT payment_method,\n COUNT(*) AS orders,\n COUNT(DISTINCT customer_id) AS unique_buyers\nFROM orders\nGROUP BY 1\nORDER BY orders DESC"}, {"category": "Date & Time", "name": "Monthly revenue", "description": "DATE_TRUNC is the workhorse of time-series SQL", "query": "SELECT DATE_TRUNC('month', order_date) AS month,\n COUNT(*) AS orders,\n ROUND(SUM(total_amount), 2) AS revenue\nFROM orders\nWHERE status = 'completed'\nGROUP BY 1\nORDER BY 1"}, {"category": "Date & Time", "name": "Day-of-week pattern", "description": "Which weekdays sell the most?", "query": "SELECT DAYNAME(order_date) AS weekday,\n COUNT(*) AS orders,\n ROUND(AVG(total_amount), 2) AS avg_value\nFROM orders\nGROUP BY weekday, DAYOFWEEK(order_date)\nORDER BY DAYOFWEEK(order_date)"}, {"category": "Date & Time", "name": "Hour-of-day distribution", "description": "EXTRACT pulls any date part", "query": "SELECT EXTRACT(hour FROM order_date) AS hour, COUNT(*) AS orders\nFROM orders\nGROUP BY 1\nORDER BY 1"}, {"category": "Date & Time", "name": "Signup-to-first-order gap", "description": "DATE_DIFF between two event dates per customer", "query": "SELECT c.customer_id, c.created_at,\n MIN(o.order_date) AS first_order,\n DATE_DIFF('day', c.created_at, MIN(o.order_date)) AS days_to_first_order\nFROM customers c\nJOIN orders o ON o.customer_id = c.customer_id\nGROUP BY 1, 2\nHAVING DATE_DIFF('day', c.created_at, MIN(o.order_date)) >= 0\nORDER BY days_to_first_order\nLIMIT 15"}, {"category": "Date & Time", "name": "Quarterly summary", "description": "QUARTER() for coarse-grained reporting", "query": "SELECT QUARTER(order_date) AS quarter,\n COUNT(*) AS orders,\n ROUND(SUM(total_amount), 2) AS revenue\nFROM orders\nWHERE status = 'completed'\nGROUP BY 1\nORDER BY 1"}, {"category": "Date & Time", "name": "Signup cohort sizes", "description": "Customers grouped by signup month", "query": "SELECT DATE_TRUNC('month', created_at) AS signup_month,\n COUNT(*) AS new_customers,\n SUM(COUNT(*)) OVER (ORDER BY DATE_TRUNC('month', created_at)) AS running_total\nFROM customers\nGROUP BY 1\nORDER BY 1"}, {"category": "Window Functions", "name": "Latest order per customer", "description": "ROW_NUMBER + QUALIFY to keep one row per group", "query": "SELECT customer_id, order_id, order_date, total_amount\nFROM orders\nQUALIFY ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) = 1\nORDER BY customer_id\nLIMIT 20"}, {"category": "Window Functions", "name": "Product rank within category", "description": "RANK and DENSE_RANK compared side by side", "query": "SELECT p.category, p.name,\n SUM(oi.quantity * oi.unit_price) AS revenue,\n RANK() OVER (PARTITION BY p.category ORDER BY SUM(oi.quantity * oi.unit_price) DESC) AS rnk,\n DENSE_RANK() OVER (PARTITION BY p.category ORDER BY SUM(oi.quantity * oi.unit_price) DESC) AS dense_rnk\nFROM products p\nJOIN order_items oi ON oi.product_id = p.product_id\nGROUP BY p.category, p.name\nQUALIFY rnk <= 3\nORDER BY p.category, rnk"}, {"category": "Window Functions", "name": "Running revenue total", "description": "Cumulative sum over ordered daily revenue", "query": "WITH daily AS (\n SELECT CAST(order_date AS DATE) AS day, SUM(total_amount) AS revenue\n FROM orders WHERE status = 'completed' GROUP BY 1\n)\nSELECT day, revenue,\n SUM(revenue) OVER (ORDER BY day) AS cumulative_revenue\nFROM daily\nORDER BY day\nLIMIT 31"}, {"category": "Window Functions", "name": "7-day moving average", "description": "Window frame: ROWS BETWEEN 6 PRECEDING AND CURRENT ROW", "query": "WITH daily AS (\n SELECT CAST(order_date AS DATE) AS day, SUM(total_amount) AS revenue\n FROM orders WHERE status = 'completed' GROUP BY 1\n)\nSELECT day, revenue,\n ROUND(AVG(revenue) OVER (ORDER BY day ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 2) AS ma_7d\nFROM daily\nORDER BY day\nLIMIT 31"}, {"category": "Window Functions", "name": "Month-over-month growth", "description": "LAG to compare each month with the previous one", "query": "WITH monthly AS (\n SELECT DATE_TRUNC('month', order_date) AS month, SUM(total_amount) AS revenue\n FROM orders WHERE status = 'completed' GROUP BY 1\n)\nSELECT month, revenue,\n LAG(revenue) OVER (ORDER BY month) AS prev_month,\n ROUND(100.0 * (revenue - LAG(revenue) OVER (ORDER BY month))\n / NULLIF(LAG(revenue) OVER (ORDER BY month), 0), 1) AS growth_pct\nFROM monthly\nORDER BY month"}, {"category": "Window Functions", "name": "Customer spend quartiles", "description": "NTILE(4) buckets customers by total spend", "query": "WITH spend AS (\n SELECT customer_id, SUM(total_amount) AS total_spend\n FROM orders WHERE status = 'completed' GROUP BY 1\n), tiled AS (\n SELECT customer_id, total_spend,\n NTILE(4) OVER (ORDER BY total_spend) AS quartile\n FROM spend\n)\nSELECT quartile,\n COUNT(*) AS customers,\n ROUND(MIN(total_spend), 2) AS min_spend,\n ROUND(AVG(total_spend), 2) AS avg_spend,\n ROUND(MAX(total_spend), 2) AS max_spend\nFROM tiled\nGROUP BY quartile\nORDER BY quartile"}, {"category": "Window Functions", "name": "Share of total revenue", "description": "SUM() OVER () with no partition = grand total", "query": "SELECT p.category,\n SUM(oi.quantity * oi.unit_price) AS revenue,\n ROUND(100.0 * SUM(oi.quantity * oi.unit_price) / SUM(SUM(oi.quantity * oi.unit_price)) OVER (), 1) AS pct_of_total\nFROM products p\nJOIN order_items oi ON oi.product_id = p.product_id\nGROUP BY p.category\nORDER BY revenue DESC"}, {"category": "Window Functions", "name": "First and latest order per customer", "description": "MIN/MAX as window functions preserve detail rows", "query": "SELECT DISTINCT customer_id,\n MIN(order_date) OVER (PARTITION BY customer_id) AS first_order,\n MAX(order_date) OVER (PARTITION BY customer_id) AS latest_order\nFROM orders\nORDER BY customer_id\nLIMIT 20"}, {"category": "CTEs & Subqueries", "name": "CTE: high-value customers", "description": "Name an intermediate result, then join against it", "query": "WITH big_spenders AS (\n SELECT customer_id, SUM(total_amount) AS spend\n FROM orders WHERE status = 'completed'\n GROUP BY 1\n HAVING SUM(total_amount) > 1500\n)\nSELECT c.name, c.country, c.segment, b.spend\nFROM big_spenders b\nJOIN customers c ON c.customer_id = b.customer_id\nORDER BY b.spend DESC\nLIMIT 20"}, {"category": "CTEs & Subqueries", "name": "Multi-CTE funnel", "description": "Chained CTEs: base revenue → country totals → top 3", "query": "WITH completed AS (\n SELECT * FROM orders WHERE status = 'completed'\n), by_country AS (\n SELECT c.country, SUM(o.total_amount) AS revenue\n FROM completed o JOIN customers c ON c.customer_id = o.customer_id\n GROUP BY 1\n)\nSELECT * FROM by_country ORDER BY revenue DESC LIMIT 3"}, {"category": "CTEs & Subqueries", "name": "Orders above the customer's own average", "description": "Correlated subquery — re-evaluated per outer row", "query": "SELECT o.customer_id, o.order_id, o.total_amount\nFROM orders o\nWHERE o.status = 'completed'\n AND o.total_amount > 1.8 * (\n SELECT AVG(o2.total_amount) FROM orders o2\n WHERE o2.customer_id = o.customer_id AND o2.status = 'completed'\n )\nORDER BY o.total_amount DESC\nLIMIT 20"}, {"category": "CTEs & Subqueries", "name": "Orders vs global average", "description": "Scalar subquery used inline in an expression", "query": "SELECT order_id, total_amount,\n ROUND(total_amount - (SELECT AVG(total_amount) FROM orders WHERE status = 'completed'), 2) AS vs_avg\nFROM orders\nWHERE status = 'completed'\nORDER BY vs_avg DESC\nLIMIT 15"}, {"category": "CTEs & Subqueries", "name": "Recursive CTE: month spine", "description": "WITH RECURSIVE generating the 12 months of 2024", "query": "WITH RECURSIVE months(month_start) AS (\n SELECT DATE '2024-01-01'\n UNION ALL\n SELECT month_start + INTERVAL 1 MONTH FROM months\n WHERE month_start < DATE '2024-12-01'\n)\nSELECT m.month_start,\n COALESCE(SUM(o.total_amount), 0) AS revenue\nFROM months m\nLEFT JOIN orders o\n ON DATE_TRUNC('month', o.order_date) = m.month_start AND o.status = 'completed'\nGROUP BY 1\nORDER BY 1"}, {"category": "CTEs & Subqueries", "name": "IN with a subquery", "description": "Customers from the single top revenue country", "query": "SELECT name, email, segment\nFROM customers\nWHERE country IN (\n SELECT c.country\n FROM customers c JOIN orders o ON o.customer_id = c.customer_id\n WHERE o.status = 'completed'\n GROUP BY c.country\n ORDER BY SUM(o.total_amount) DESC\n LIMIT 1\n)\nLIMIT 20"}, {"category": "Business Analytics", "name": "Pareto (80/20) analysis", "description": "Cumulative revenue share — how few products drive most revenue", "query": "WITH product_revenue AS (\n SELECT p.name, SUM(oi.quantity * oi.unit_price) AS revenue\n FROM products p JOIN order_items oi ON oi.product_id = p.product_id\n GROUP BY 1\n)\nSELECT name, revenue,\n ROUND(100.0 * SUM(revenue) OVER (ORDER BY revenue DESC) / SUM(revenue) OVER (), 1) AS cumulative_pct\nFROM product_revenue\nORDER BY revenue DESC\nLIMIT 25"}, {"category": "Business Analytics", "name": "RFM scores", "description": "Recency / Frequency / Monetary quintiles per customer", "query": "WITH per_customer AS (\n SELECT customer_id,\n MAX(order_date) AS last_order,\n COUNT(*) AS frequency,\n SUM(total_amount) AS monetary\n FROM orders WHERE status = 'completed'\n GROUP BY 1\n)\nSELECT customer_id,\n NTILE(5) OVER (ORDER BY last_order) AS r_score,\n NTILE(5) OVER (ORDER BY frequency) AS f_score,\n NTILE(5) OVER (ORDER BY monetary) AS m_score,\n frequency, ROUND(monetary, 2) AS monetary\nFROM per_customer\nORDER BY monetary DESC\nLIMIT 20"}, {"category": "Business Analytics", "name": "Cohort retention", "description": "Signup cohort vs months-to-order matrix (FILTER pivots)", "query": "WITH cohorts AS (\n SELECT c.customer_id, DATE_TRUNC('month', c.created_at) AS cohort_month\n FROM customers c\n), activity AS (\n SELECT ch.cohort_month,\n DATE_DIFF('month', ch.cohort_month, DATE_TRUNC('month', o.order_date)) AS month_offset,\n o.customer_id\n FROM cohorts ch JOIN orders o ON o.customer_id = ch.customer_id\n WHERE o.status = 'completed'\n)\nSELECT cohort_month,\n COUNT(DISTINCT customer_id) FILTER (WHERE month_offset = 0) AS m0,\n COUNT(DISTINCT customer_id) FILTER (WHERE month_offset = 1) AS m1,\n COUNT(DISTINCT customer_id) FILTER (WHERE month_offset = 2) AS m2,\n COUNT(DISTINCT customer_id) FILTER (WHERE month_offset = 3) AS m3\nFROM activity\nGROUP BY 1\nORDER BY 1"}, {"category": "Business Analytics", "name": "Repeat purchase rate", "description": "Share of customers with two or more completed orders", "query": "WITH order_counts AS (\n SELECT customer_id, COUNT(*) AS n\n FROM orders WHERE status = 'completed'\n GROUP BY 1\n)\nSELECT COUNT(*) AS buyers,\n COUNT(*) FILTER (WHERE n >= 2) AS repeat_buyers,\n ROUND(100.0 * COUNT(*) FILTER (WHERE n >= 2) / COUNT(*), 1) AS repeat_rate_pct\nFROM order_counts"}, {"category": "Business Analytics", "name": "Average order value trend", "description": "Monthly AOV with order counts for context", "query": "SELECT DATE_TRUNC('month', order_date) AS month,\n COUNT(*) AS orders,\n ROUND(AVG(total_amount), 2) AS avg_order_value\nFROM orders\nWHERE status = 'completed'\nGROUP BY 1\nORDER BY 1"}, {"category": "Business Analytics", "name": "Revenue per customer by segment", "description": "A simple lifetime-value proxy per segment", "query": "SELECT c.segment,\n COUNT(DISTINCT c.customer_id) AS customers,\n ROUND(SUM(o.total_amount), 2) AS revenue,\n ROUND(SUM(o.total_amount) / COUNT(DISTINCT c.customer_id), 2) AS revenue_per_customer\nFROM customers c\nJOIN orders o ON o.customer_id = c.customer_id AND o.status = 'completed'\nGROUP BY 1\nORDER BY revenue_per_customer DESC"}, {"category": "Business Analytics", "name": "Products bought together", "description": "Market-basket pairs via a self join on order_id", "query": "SELECT p1.name AS product_a, p2.name AS product_b, COUNT(*) AS times_together\nFROM order_items a\nJOIN order_items b ON a.order_id = b.order_id AND a.product_id < b.product_id\nJOIN products p1 ON p1.product_id = a.product_id\nJOIN products p2 ON p2.product_id = b.product_id\nGROUP BY 1, 2\nORDER BY times_together DESC\nLIMIT 10"}, {"category": "Business Analytics", "name": "Refund rate by category", "description": "Conditional aggregation across joined tables", "query": "SELECT p.category,\n COUNT(DISTINCT o.order_id) AS orders,\n COUNT(DISTINCT o.order_id) FILTER (WHERE o.status = 'refunded') AS refunded,\n ROUND(100.0 * COUNT(DISTINCT o.order_id) FILTER (WHERE o.status = 'refunded')\n / COUNT(DISTINCT o.order_id), 2) AS refund_rate_pct\nFROM orders o\nJOIN order_items oi ON oi.order_id = o.order_id\nJOIN products p ON p.product_id = oi.product_id\nGROUP BY 1\nORDER BY refund_rate_pct DESC"}, {"category": "Business Analytics", "name": "New vs returning revenue", "description": "Classify each order against the customer's first order month", "query": "WITH firsts AS (\n SELECT customer_id, MIN(DATE_TRUNC('month', order_date)) AS first_month\n FROM orders WHERE status = 'completed' GROUP BY 1\n)\nSELECT DATE_TRUNC('month', o.order_date) AS month,\n ROUND(SUM(o.total_amount) FILTER (WHERE DATE_TRUNC('month', o.order_date) = f.first_month), 2) AS new_customer_revenue,\n ROUND(SUM(o.total_amount) FILTER (WHERE DATE_TRUNC('month', o.order_date) > f.first_month), 2) AS returning_revenue\nFROM orders o\nJOIN firsts f ON f.customer_id = o.customer_id\nWHERE o.status = 'completed'\nGROUP BY 1\nORDER BY 1"}]