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.
Q87Show every order_id with its month-name + year: '#' || order_id || ' in ' || TO_CHAR(order_date, 'FMMonth YYYY').
Q88Trim+INITCAP the ticket subject and prefix with 'TICKET-' || ticket_id.
Q89Build a 'days since last activity' indicator for every shipment: CURRENT_DATE - shipped_date with a ' days ago' suffix.
Q90Show every customer's account age in 'Y years M months' format using AGE + EXTRACT.
Q91Concat region info: 'Order from store ' || store_id || ' on ' || TO_CHAR(order_date, 'YYYY-MM-DD').
Q92For every page_view, build a session label: 'Session ' || session_id || ' viewed ' || page_url + ' at ' + TO_CHAR(view_timestamp, 'HH24:MI:SS').
Q93For every call_center.calls row, build a string 'Call #' || call_id || ' by agent ' || agent_id || ' at ' || TO_CHAR(call_start_time, 'DD-Mon HH24:MI').
Q94Show every loyalty member with their tier_id and 'joined ' || EXTRACT(YEAR FROM AGE(join_date)) || ' years ago'.
Q95Build a customer display: customer_id, INITCAP(first_name || ' ' || last_name), and EXTRACT(YEAR FROM AGE(registration_date)) || ' yrs as customer'.
Q96For each work order, show 'WO-' || work_order_id || ' produced ' || quantity_produced || ' units on ' || TO_CHAR(end_timestamp, 'DD-Mon-YYYY').
Q97For each expense, show 'Exp #' || expense_id || ' - Rs' || amount || ' on ' || TO_CHAR(expense_date, 'DD-Mon-YYYY').
Q98For every customer review, show 'REVIEW ' || review_id || ': ' || rating || '* on ' || TO_CHAR(review_date, 'DD-Mon-YYYY').
Q99Show every API request: status_code || ' ' || method || ' ' || endpoint + ' at ' + TO_CHAR(timestamp, 'HH24:MI:SS').
Q100Build a 'days remaining in current month' utility: (DATE_TRUNC('month', CURRENT_DATE) + INTERVAL '1 month' - 1 day) - CURRENT_DATE.
Combined ideas, multi-step thinking
STRING / DATE DEEPER CONCEPTUAL
Q1What does NULL || 'abc' return - and how do you avoid the NULL trap?
Q2Difference between SUBSTRING and SUBSTR in PostgreSQL.
Q3Compare LIKE '%abc%' vs the regex operator ~ 'abc' - which is case-insensitive?
Q4Explain LATERAL vs subqueries in the context of expanding REGEXP_MATCHES result.
Q5What does TO_CHAR(num, '99G99G999') do - what's the G?
Q6Compare TO_CHAR(date, 'Mon') vs 'FMMon' - what's the difference in output?
Q7Why is EXTRACT(EPOCH FROM ...) needed when AGE() returns an interval?
Q8What does JUSTIFY_INTERVAL do?
Q9Compare TO_DATE('2025-01-15', 'YYYY-MM-DD') vs '2025-01-15'::DATE.
Q10Why does NOW() inside a transaction always return the SAME time?
Q11Explain CURRENT_TIMESTAMP vs STATEMENT_TIMESTAMP vs CLOCK_TIMESTAMP.
Q12What's the difference between AGE(d1) and AGE(d1, d2)?
Q13Why is DATE_TRUNC('week', date) potentially confusing for Indian users (week starts when?).
Q14Compare INTERVAL '1 month' vs adding 30 days - when do they differ?
Q15What does the TIMEZONE function do - give a use case.
Q16Explain LPAD and RPAD with one example each.
Q17What's the difference between OVERLAY and SUBSTRING?
Q18What does REGEXP_REPLACE do - give one cleaning use case.
Q19Compare REGEXP_MATCHES (returns text[]) vs REGEXP_MATCH (returns text).
Q20When would you use REGEXP_SPLIT_TO_TABLE vs REGEXP_SPLIT_TO_ARRAY?
Q21Why is STRPOS(text, substring) sometimes preferred over POSITION(substring IN text)?
Q22Explain what FORMAT() does - give a SQL injection-safe example.
Q23Difference between TO_NUMBER('1,234.50', '9,999.99') and '1234.50'::NUMERIC.
Q24Why does LENGTH on a TEXT with multi-byte characters return character count, not bytes - and where's the byte-count?
Q25How do you find the WEEK NUMBER of a date in PostgreSQL? What's the difference between 'WW' and 'IW'?
NESTED STRING FUNCTIONS
Q26Show customer's full_name with first character of each part capitalized + collapse multiple spaces (nested INITCAP + REGEXP_REPLACE).
Q90Build a transcript snippet: LEFT(transcript_text, 100) || '...' if longer than 100 else transcript_text.
Q91Build a search-friendly product slug for URL: LOWER(REGEXP_REPLACE(product_name, '[^a-zA-Z0-9]+', '-', 'g')) || '-' || product_id.
Q92Build a customer JSON summary as text: '{"id":' || customer_id || ',"name":"' || first_name || '","tier":"' || tier || '"}'.
Q93Build a 'last seen' label using AGE for each customer: based on most recent page_view. (Single-table tip: use a placeholder MAX timestamp.)
Q94Build a 'days since hire' label per employee.
Q95Build a fiscal-year label (FY24, FY25) for each order_date assuming FY = April-March.
Q96Build a date-bucket label per order: 'today' / 'yesterday' / 'this_week' / 'this_month' / 'older'.
Q97Build a 'shipped-but-not-delivered for X days' label per shipment.
Q98Build a 'high-value' flag string per order: order_id + ' [HIGH]' if net_total > 10000 else order_id + ' [normal]'.
Q99Build a sentiment summary per call: 'Call ' || call_id || ' - sentiment ' || CASE WHEN sentiment_score >= 0.5 THEN 'positive' WHEN sentiment_score <= -0.5 THEN 'negative' ELSE 'neutral' END (from transcripts joined to calls).
Q100Build an aging report: every unresolved ticket with 'Ticket ' || ticket_id || ' open ' || (CURRENT_DATE - created_date::DATE) || ' days; priority ' || priority.
Interview grade, edge cases
SCALAR FUNCTIONS - CONCEPTUAL
Q1What's the difference between LIKE, ILIKE, ~, ~*, ~~, ~~* in Postgres?
Q2Compare regexp_match vs regexp_matches - which returns multiple?
Q3Explain regexp_split_to_array vs string_to_array.
Q4Why does \d work in Postgres regex but \d+ inside SQL string needs '\\d+'?
Q5What is the SUBSTRING(... FROM regex) form - and how is it useful?
Q6Compare to_char(now(), 'YYYY-MM-DD') vs ::date - both for date display.
Q7Explain AGE(end, start) - what does it return vs (end - start)?
Q8Compare INTERVAL '1 month' vs INTERVAL '30 days' - when do they differ?
Q9Why does CURRENT_TIMESTAMP return the txn-start time, not now()?
Q10Compare now() vs statement_timestamp() vs clock_timestamp().
Q11Explain AT TIME ZONE - when does it convert vs assign?
Q12What is DATE_TRUNC('week', ts) - and which day starts the week in Postgres?
Q13How do you compute "business days between two dates" - give a SQL approach.
Q14What is EXTRACT(EPOCH FROM ts) - and when is it useful?
Q15Compare md5() vs sha256() (with pgcrypto) - when does each apply?
Q16What is encode(bytea, 'hex' | 'base64') - and decode() reverse.
Q17Explain url_encode (via plpgsql) - Postgres doesn't ship it; how do you build it?
Q18What is to_tsvector - and why is it needed for full-text search?
Q19Why are functional indexes (CREATE INDEX ON t(lower(email))) essential for sargable LOWER queries?
Q20Compare CAST(x AS TYPE) vs x::TYPE - when does each fail differently.
Q21What is FORMAT() - when is it preferred over string concatenation?
Q22Explain how STRING_AGG with ORDER BY produces ordered concatenated lists.
Q23Compare JSON_BUILD_OBJECT vs ROW_TO_JSON - when each.
Q24Explain GENERATED ALWAYS AS (lower(email)) STORED - when use it.
Q25What is the IMMUTABLE / STABLE / VOLATILE function classification - and why does it matter for indexes?
REGEX & STRING ADVANCED
Q26Validate email with regex: SELECT email FROM customers WHERE email ~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'.
Q27Extract domain from email using regexp_match.
Q28Extract phone country code: regexp_match(phone, '^\+(\d{1,3})').
Q29Split full_name into first/last/middle via regexp_split_to_array.
Q30Find customers whose email contains digits: WHERE email ~ '\d'.
Q31Strip non-digit characters from phone: regexp_replace(phone, '\D', '', 'g').
Q32Mask middle of phone: regexp_replace(phone, '(.{3})(.+)(.{2})', '\1***\3').
Q33Extract hashtags from a review_text: regexp_matches(review_text, '#(\w+)', 'g').
Q34Find customers with consecutive duplicate letters: WHERE full_name ~ '([a-z])\1'.
Q35Validate Indian PIN code: WHERE pin_code ~ '^\d{6}$'.
Q36Find emails with uncommon TLDs: WHERE email !~ '\.(com|net|org|in)$'.
Q37Replace whitespace with underscore: regexp_replace(name, '\s+', '_', 'g').
Q38Extract numbers from product codes: regexp_replace(code, '[^0-9]', '', 'g').
Q39Find duplicate words in subject: WHERE subject ~ '\\m(\\w+)\\M.*\\1'.
Q40Use SIMILAR TO for SQL-standard pattern: WHERE name SIMILAR TO '[A-Z][a-z]+'.
Q41Build a "slug" from a title: lower(regexp_replace(title, '\W+', '-', 'g')).
Q42Extract third word: split_part(text, ' ', 3).
Q43Find palindrome strings: WHERE col = reverse(col).
Q44Count vowels in a string: char_length(col) - char_length(regexp_replace(col, '[aeiou]', '', 'gi')).
Q45Truncate string at first whitespace: split_part(col, ' ', 1).
Q46CASE-INSENSITIVE email match using LOWER + functional index.
Q47URL-encode a parameter (DIY using regexp_replace).