400 questions in four levels, all on RetailMart, the practice database of this course. Write every query yourself, get it wrong, read the error, fix it. That is how it sticks.
Q68Safe division: page_views per customer ID, dividing 1 by NULLIF(customer_id, 0).
Q69Build a fallback chain for product price: COALESCE(price, cost_price, 0).
Q70For sales.shipments, courier_name with fallback: COALESCE(courier_name, 'Unknown Courier').
CAST / TYPE CONVERSIONS
Q71Cast order_id (INT) to TEXT and concatenate: 'Order ' || order_id::TEXT.
Q72Cast price (NUMERIC) to INT to round down - products.products.
Q73Cast net_total to a 2-decimal NUMERIC (ROUND alternative) - sales.orders.
Q74Cast registration_date (DATE) to TEXT in 'YYYY-MM-DD' format via TO_CHAR (the proper way).
Q75Cast text '2025-01-15' to DATE explicitly using ::DATE.
Q76Cast '12.50' to NUMERIC.
Q77Cast '12.50' to NUMERIC(10,2).
Q78Cast a field to TEXT using ::TEXT (web_events.events.event_type).
Q79Cast api_requests.status_code (INT) to TEXT before concatenation.
Q80Cast call_duration_seconds to interval: (call_duration_seconds || ' seconds')::INTERVAL.
Q81Cast quantity_produced (INT) to NUMERIC to get a decimal in division: quantity_produced::NUMERIC / 100.
Q82Cast amount (NUMERIC) to INT for finance.expenses for a simplified summary.
Q83Cast TIMESTAMP to DATE - sales.shipments.shipped_date is already DATE; pick a TIMESTAMP column: web_events.page_views.view_timestamp::DATE.
Q84Cast attendance check_in (TIMESTAMP) to TIME using ::TIME.
Q85Cast attendance check_in to DATE.
Q86Cast a string '1' to BOOLEAN... actually BOOLEAN expects 't' or 'true' - try (value = 'true')::BOOLEAN. Or simpler: 'true'::BOOLEAN.
Q87Cast a NUMERIC like 0.85 to TEXT with TO_CHAR(0.85, '0.00%') for percent display.
Q88Cast products.price to BIGINT (no precision needed for whole-number price).
Q89Cast '100' to INT explicitly using CAST syntax: CAST('100' AS INT).
Q90Show TO_CHAR with format 'FM99,99,999' for Indian-style price grouping on products.price.
Q91Cast text '99.99' to NUMERIC and add 0.01 - result should be 100.00.
Q92Show TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS') - current timestamp as ISO-ish string.
Q93Cast review_date to TEXT using ::TEXT (default formatting).
Q94Cast customer_id (INT) to TEXT and pad with leading zeros using LPAD: LPAD(customer_id::TEXT, 8, '0').
Q95Cast salary (NUMERIC) to INT - drop the decimal.
Q96For sales.orders, cast net_total to INT and prefix with 'Rs': 'Rs' || net_total::INT.
Q97Cast text to JSONB: '{"role": "admin"}'::JSONB.
Q98Cast UUID to TEXT for display in a report.
Q99Cast '2025' (text) to INT - should be 2025.
Q100Build a display: order_id::TEXT || ' (' || TO_CHAR(net_total, 'FMRs99,99,999') || ')' for invoice-like label.
Combined ideas, multi-step thinking
CONDITIONAL LOGIC DEEPER - CONCEPTUAL
Q1Compare CASE in WHERE vs CASE in SELECT - when does each shine?
Q2What's the difference between Simple CASE and Searched CASE - give example of each.
Q3Can a CASE return different DATA TYPES from different WHEN branches?
Q4Explain CASE inside SUM - what does SUM(CASE WHEN ... THEN net_total END) compute?
Q5Compare COALESCE(a, b, c) vs CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ELSE c END.
Q6Why is NULLIF(x, 0) commonly used in a division denominator?
Q7Explain CAST('12.5' AS INT) vs '12.5'::INT - same result?
Q8What is the difference between :: (PostgreSQL cast) and CAST (SQL-standard)?
Q9Why does casting '2025-13-01'::DATE fail - what's the rule for valid dates?
Q10What's the type-conversion priority of CASE: if branches return TEXT and INT mixed, what does the optimizer do?
Q11Explain how CASE evaluates short-circuit: does it eval all branches or stop at first match?
Q12Why is CASE WHEN x = NULL THEN 'a' always FALSE - and what should you use instead?
Q13Compare COALESCE(a, b) and a IS DISTINCT FROM b - when do they relate?
Q14Why is NULLIF useful for sentinel values like empty string?
Q15Can CAST happen implicitly - give two cases when PostgreSQL silently casts.
Q16Difference between IS NULL and = NULL - why does the second never work?
Q17Compare CAST(x AS TEXT) vs x::TEXT vs TO_CHAR(x, ...) - when do you choose each?
Q18What happens if all WHEN branches in a CASE return NULL but there's no ELSE?
Q19Why is GREATEST(a, b, c) related to MAX in spirit but different in scope?
Q20Can you nest CASE inside CASE - give a use case.
Q21What happens when COALESCE arguments include different types (INT, TEXT)?
Q22When does CAST silently truncate vs error? Example: NUMERIC -> INT vs TEXT -> INT.
Q23Why does NULLIF(NULL, 0) return NULL, not 0?
Q24Compare CASE expression vs COALESCE for readability - which is preferred for fallback chains?
Q25Why is CAST(price AS NUMERIC(10,2)) safer than CAST(price AS NUMERIC) in production?
NESTED + COMBINED CASE
Q26Classify customers into 'Premium' (Gold/Platinum) -> further into 'Loyal' (registered >= 3 yrs) vs 'New Premium' (< 3 yrs). Use NESTED CASE.
Q27Classify orders: high-value (> 10000) AND Delivered -> 'A'; high-value AND not delivered -> 'B'; low-value AND Delivered -> 'C'; else 'D'.
Q28Bucket products: brand IS NULL -> 'Unknown brand'; ELSE bucket by price (cheap/mid/premium).
Q29Combine CASE + LIKE: classify employees by role pattern: contains 'Manager' -> 'Mgr'; contains 'Engineer' -> 'Eng'; else 'Other'.
Q30Combine CASE + EXTRACT(DOW): label each order_date as 'Weekend' (DOW IN 0,6) or weekday name.
Q31Build a customer "lifecycle stage" label using 3+ conditions: tier + registration_date + (assume) order count > N.
Q32Show every ticket with a 'severity_score' INT: priority=Critical->4, High->3, Medium->2, Low->1, else 0.
Q33Show every order with an 'urgency_label': order_status='Delivered' -> 'Done'; 'Pending' -> 'Urgent if > 7 days old' else 'OK'; etc.
Q34Conditional aggregation preview: SUM(CASE WHEN order_status='Delivered' THEN net_total END) AS delivered_revenue from sales.orders.
Q35Conditional COUNT: COUNT(CASE WHEN rating = 5 THEN 1 END) AS five_stars from customers.reviews.
Q36Show every employee with bracket: salary < 30K -> 'Junior'; < 60K -> 'Mid'; < 100K -> 'Senior'; else 'Executive'.
Q37Build a 'safety score' from sales.shipments using CASE: delivered same day as shipped -> 5; 1-2 days -> 4; 3-7 days -> 3; > 7 days -> 2; not delivered -> 1.
Q38Bucket product reviews using BOTH rating and length(comment): 5-star with long comment -> 'Detailed praise'; 5-star with no comment -> 'Quick like'; etc.
Q39Conditional aggregation: SUM of net_total only for orders placed on weekends.
Q40Use CASE inside ORDER BY: sort by priority custom order (Critical first, then High, Medium, Low).
Q41Show every customer with their tier_rank: Bronze=1, Silver=2, Gold=3, Platinum=4 - useful as a sort key.
Q42Build a hierarchical label: combine tier + registration year as a label like 'Gold-2024'.
Q43Use CASE to show only specific months by name (filter via WHERE doesn't quite fit - use CASE in SELECT to label 'Q1', 'Q2', 'Q3', 'Q4').
Q44Build a 'days_to_action' field: if status='Delivered' return delivered_date - order_date; else CURRENT_DATE - order_date.
Q45Show every order with a 'paid_status' derived from sales.payments via a subquery + CASE (paid in full, partial, unpaid).
Q46Compute the GREATEST of three: GREATEST(price, cost_price, 100) from products.products.
Q47Compute the LEAST of three: LEAST(price, cost_price, 100).
Q48Use CASE to detect "this row is the FIRST order of its customer" - show ticket_id with a Y/N marker (correlated subquery for MIN).
Q49Build a CASE that converts hr.attendance check_in into a shift label: < 6am 'Night', < 12pm 'Morning', < 6pm 'Day', else 'Evening'.
Q50Combine CASE + INTERVAL: tag every ticket as 'Fast' if resolved within 1 hour, 'Same Day' if same day, 'Slow' otherwise.
COALESCE / NULLIF CHAINS
Q51For each customer, prefer phone, fall back to email, fall back to 'NO CONTACT' - single COALESCE chain.
Q52For each shipment, show "delivered_date OR shipped_date + 5 days OR CURRENT_DATE" - three-level COALESCE.
Q53For each loyalty member, show next_tier_threshold using COALESCE on points_balance vs benchmarks.
Q54NULLIF(LENGTH(TRIM(subject)), 0) - convert empty/whitespace-only subjects to NULL on tickets.
Q55NULLIF(price, 0) prevents divide-by-zero in margin calc.
Q56Safe percentage: 100.0 * good_count / NULLIF(total_count, 0) - apply to a real RetailMart aggregate.
Q57COALESCE multiple email columns into one preferred email (real-world: contact_email, billing_email, alt_email).
Q58Replace ALL "" with NULL on the fly: NULLIF(TRIM(col), '') for every text column you select.
Q59COALESCE(t.tier_name, 'No Tier') for customers who aren't loyalty members.
Q60COALESCE(refund_amount, 0) for returns awaiting refund.
Q61Show every customer's tier OR 'Standard' if NULL - single-line.
Q62COALESCE inside a SUM: SUM(COALESCE(refund_amount, 0)) so NULLs count as 0.
Q63NULLIF(end_date, '9999-12-31') - turn sentinel dates back into NULL.
Q64COALESCE on JSONB key access: payload->>'city' OR 'unknown'.
Q65Triple COALESCE: city from addresses -> city from store -> 'India' as final fallback.
Q66Build "Hello [name]!" greeting using COALESCE first_name, last_name, email, 'Guest'.
Q67NULLIF for whitespace-only emails: NULLIF(TRIM(email), '').
Q68For payments, COALESCE(amount, 0) AS amount when amount might be NULL.
Q69For employees, COALESCE(store_id::TEXT, 'HQ') so HQ staff get a label, not NULL.
Q70COALESCE customer tier_updated_at OR registration_date AS effective_change_date.
Q71Show shipments with: status if not NULL, else 'In Transit' if shipped_date IS NOT NULL, else 'Unknown'.
Q72For tickets, COALESCE category, 'General' AS effective_category.
Q73For finance.expenses, COALESCE(description, 'No description') for display.
Q74For api_requests, COALESCE(user_agent, 'unknown') AS ua.
Q75NULLIF + COALESCE combo: COALESCE(NULLIF(TRIM(first_name), ''), 'Unknown') AS clean_first.
CAST + PRODUCTION COMBOS
Q76Build an invoice string with multiple CASTs: 'Order #' || order_id::TEXT || ' (Rs' || net_total::TEXT || ')'.
Q77Cast products.price to ROUND-friendly NUMERIC(10,2).
Q78Cast view_timestamp::DATE to bucket page_views by date.
Q79Use ::INTERVAL to cast '300 seconds' for a call into an interval.
Q80Combine ::DATE + ::TIME on hr.attendance check_in for separate display.
Q81Use TO_CHAR(price, 'FMRs99,99,999.00') to display Indian-style currency.
Q82Use TO_CHAR(order_date, 'FMDay, DD Mon YYYY') for a friendly date display.
Q83Show every employee's age_in_years using EXTRACT(YEAR FROM AGE(joining_date))::INT.
Q84Show every customer with their preferred display name: full name OR email OR 'Customer #' || customer_id.
Q85Combine CASE + CAST: bucket products by price, return a labeled string.
Q86Build a "stock alert" line per product: 'PRODUCT-' || product_id::TEXT || ': ' || product_name || ' is ' || CASE WHEN in_stock THEN 'IN STOCK' ELSE 'OUT' END.
Q87Build an order summary: order_id, customer name (INITCAP), net_total (FORMATTED), status (UPPER), date (TO_CHAR).
Q88Build a ticket aging banner: 'AGING ' || (CURRENT_DATE - created_date::DATE)::TEXT || ' DAYS - PRIORITY ' || UPPER(priority) for open tickets.
Q89Build a customer status row: tier (COALESCE), tenure (years), and a SAFE-divided "points-per-year" using NULLIF.
Q90Build a 'risk' flag for sales.shipments combining CASE + NULLIF: high risk if delayed > 14 days AND not yet delivered.
Q91Cast loyalty.members.points_balance to BIGINT to support summed totals over many customers.
Q92Combine CASE + CAST + COALESCE: show every payment with amount (COALESCE 0), mode (CASE in-store/online), and date (TO_CHAR).
Q93Build a refund_request_age in days using CASE on refund_amount IS NULL plus date arithmetic.
Q94For each customer, compute a "spend tier" using a single CASE on a (hypothetical) total_spend, with NULLIF for missing data.
Q95Show every employee with a 'shift' classification using CASE on EXTRACT(HOUR FROM check_in), and treat NULL check_in as 'Absent'.
Q96Show every product with 'margin_pct' = ROUND(100.0 * (price - cost_price) / NULLIF(price, 0), 2) - safe division.
Q97Compute the 'pay component split' per pay_slip: basic %, hra %, allowances %, taxes %, net % using NULLIF(gross, 0).
Q98For each application_log, build a severity_int = CASE level WHEN 'FATAL' THEN 5 WHEN 'ERROR' THEN 4 WHEN 'WARN' THEN 3 WHEN 'INFO' THEN 2 ELSE 1 END.
Q99For each api_request, compute a status_category (2xx/3xx/4xx/5xx) using CASE on status_code.
Q100Combine ALL TOOLS: For each order, show order_id, INITCAP customer name, net_total formatted, status uppercased, and 'days since' as INT - with NULL-safety throughout.
Interview grade, edge cases
CONDITIONAL LOGIC - CONCEPTUAL
Q1Compare simple CASE WHEN val=X vs searched CASE WHEN cond.
Q2Explain how CASE short-circuits - first match wins.
Q3Why does CASE inside a WHERE clause defeat indexes?
Q4Can CASE return different types per branch?
Q5What does CASE return when no WHEN matches and no ELSE - NULL.
Q6COALESCE(a, b, c, d) - what determines the chosen value?
Q7COALESCE return type - promotion rules across branches.
Q8When does COALESCE(NULL, NULL, NULL) = NULL - and how to convert to default value.
Q9NULLIF(a, b) returns NULL if a=b else a - what's the prime use case?
Q10Why does NULLIF protect against division by zero (NULLIF(denom, 0))?
Q11Compare CAST(x AS numeric) vs x::numeric - same result.
Q12What happens when CAST fails on garbage input?
Q13Why is CAST inside WHERE often non-sargable?
Q14Explain implicit vs explicit casting - and when implicit fails.
Q15Why does '1' + 1 fail in strict modes but auto-cast in Postgres?