惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News | PayPal Newsroom
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
NISL@THU
NISL@THU
WordPress大学
WordPress大学
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
Security Archives - TechRepublic
Security Archives - TechRepublic
有赞技术团队
有赞技术团队
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Latest news
Latest news
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
S
Schneier on Security
I
Intezer
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
美团技术团队
B
Blog RSS Feed

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Top 12 SQL Interview Problems for Data Engineers, With Answers
DataDriven · 2026-06-14 · via DEV Community

I've been on both sides of the SQL interview table somewhere around 20 times in a single job search. The pattern is always the same: candidates know SELECT, they know JOIN, they can write a WHERE clause. Then the interviewer asks them to deduplicate a table, find missing rows, or sessionize an event stream, and the wheels come off. Not because the syntax is hard. Because candidates don't understand what each row represents before they start writing.

32% of data engineering interview questions test GROUP BY. INNER JOIN sits at 29%, PARTITION BY at 21%, ROW_NUMBER at 15%. These twelve problems cover roughly 80% of what interviewers actually ask. Master them and you're ahead of most candidates walking into a live coding round.

Want to practice these for real? Solve these problems live here with a real editor and graded solutions.

1. Customers Who Spent Over $500

The question: Given an orders table with columns customer_id, order_date, and amount, find all customers whose total spend exceeds $500. Return customer_id and total_spent, sorted by total descending.

SELECT customer_id,
       SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 500
ORDER BY total_spent DESC;

Why it matters: 70% of candidates confuse WHERE and HAVING. SQL's execution order runs FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY. You cannot filter on an aggregate in WHERE because the aggregate doesn't exist yet. Putting SUM(amount) > 500 in WHERE is a parse error in PostgreSQL. The interviewer isn't testing whether you know HAVING exists; they're testing whether you understand when each clause runs. If you can state the execution order aloud before writing, you'll never make this mistake.

2. The Double-Counting Trap

The question: Given orders(order_id, customer_id, order_date) and order_items(item_id, order_id, product_id, quantity, price), find each customer's total revenue and total number of orders. An order can have multiple items.

WITH order_totals AS (
    SELECT order_id,
           customer_id,
           SUM(quantity * price) AS order_revenue
    FROM orders
    JOIN order_items USING (order_id)
    GROUP BY order_id, customer_id
)
SELECT customer_id,
       COUNT(*) AS num_orders,
       SUM(order_revenue) AS total_revenue
FROM order_totals
GROUP BY customer_id;

Why it matters: 80% of candidates fail the aggregation problem at Meta data engineering interviews, typically due to double-counting. If you join orders to order_items and then do COUNT(DISTINCT order_id) alongside SUM(quantity * price) in one pass, the count might look right but you've still joined at the wrong grain. The fix is CTEs: aggregate at each grain level separately, then join the results. Strong candidates use CTEs defensively. Weaker ones skip them and wonder why the revenue number is 3x too high.

3. Latest Record Per Customer

The question: Given a customer_updates table with customer_id, updated_at, email, and status, return only the most recent row per customer.

WITH ranked AS (
    SELECT *,
           ROW_NUMBER() OVER (
               PARTITION BY customer_id
               ORDER BY updated_at DESC
           ) AS rn
    FROM customer_updates
)
SELECT customer_id, updated_at, email, status
FROM ranked
WHERE rn = 1;

Why it matters: This pattern shows up in 80% of analyst and DE interview loops. The trap is candidates who reach for GROUP BY customer_id with MAX(updated_at), then realize they can't retrieve the email and status columns without aggregating them too. Window functions preserve the full row while computing per-group statistics, which is exactly why interviewers frame this as "try GROUP BY first, then reframe." The follow-up they'll push: "What happens when two rows have the same updated_at?" Your ROW_NUMBER is non-deterministic without a tiebreaker. Add a secondary sort column. Always.

4. Deterministic Deduplication With Tie-Breaking

The question: Same table as above, but now two updates can arrive at the exact same timestamp. Write a query that always returns the same row for a given customer, regardless of physical storage order.

WITH ranked AS (
    SELECT *,
           ROW_NUMBER() OVER (
               PARTITION BY customer_id
               ORDER BY updated_at DESC,
                        ctid DESC , Postgres: use a surrogate/sequence in production
           ) AS rn
    FROM customer_updates
)
SELECT customer_id, updated_at, email, status
FROM ranked
WHERE rn = 1;

Why it matters: Most candidates write the ROW_NUMBER query from Problem 3 and stop. Real production deduplication adds a secondary sort: ORDER BY updated_at DESC, source_sequence_number DESC to ensure the same row wins every run. Without it, two executions on different database instances can return different results. Interviewers probe this when your first answer looks clean. The lesson: ROW_NUMBER is deterministic in its assignment but non-deterministic in its choice when ties exist in the ORDER BY. Name the tiebreaker or admit the query is unstable.

5. Customers With No Orders (Anti-Join)

The question: Given customers(customer_id, name) and orders(order_id, customer_id, order_date), find all customers who have never placed an order.

SELECT c.customer_id, c.name
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.customer_id IS NULL;

Why it matters: Anti-joins expose whether you understand missingness. The LEFT JOIN plus IS NULL pattern finds rows in A that have no match in B. Interviewers test this because funnel leaks hide in production analytics; "which users signed up but never converted?" is exactly this query. The follow-up is always: "Would NOT EXISTS work?" Yes, and it's semantically safer when join keys might be nullable. Modern query planners treat both identically, so the choice is about clarity, not performance.

6. NOT IN vs NOT EXISTS With NULLs

The question: Given the same tables, explain why this query returns zero rows when the orders table contains a NULL customer_id:

,  This silently returns ZERO rows if any order has customer_id IS NULL
SELECT customer_id, name
FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders);

,  Safe version: NOT EXISTS handles NULLs correctly
SELECT c.customer_id, c.name
FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id
);

Why it matters: This is a silent killer in sql interview rounds. When a subquery contains even one NULL, NOT IN returns zero rows because every comparison against NULL evaluates to UNKNOWN. The query runs without error. It returns a result set. The result set is wrong. Candidates who default to NOT EXISTS signal they've been burned by this in production. Candidates who reach for NOT IN signal they haven't.

7. Recursive CTE Org Chart

The question: Given employees(employee_id, name, manager_id), find all employees (direct and indirect reports) under employee_id = 1. Return employee_id, name, and depth level.

WITH RECURSIVE org AS (
    SELECT employee_id, name, manager_id, 0 AS depth
    FROM employees
    WHERE employee_id = 1

    UNION ALL

    SELECT e.employee_id, e.name, e.manager_id, org.depth + 1
    FROM employees e
    JOIN org ON e.manager_id = org.employee_id
)
SELECT employee_id, name, depth
FROM org
ORDER BY depth, name;

Why it matters: JPMorgan explicitly asks this. Recursive CTEs separate candidates who understand anchor members, recursive members, and termination conditions from those who guess. The recursive step stops when it returns zero rows; if your data has circular references (employee A reports to B, B reports to A), you get an infinite loop. Mention this unprompted and you signal production experience. Ironically, recursive CTEs are vanishingly rare in production code because most hierarchies are shallow (3 to 5 levels) and materialized paths are faster. Interviewers test it as a proxy for "can you think recursively?" not "will you ship this?"

8. Self-Join for Consecutive-Day Logins

The question: Given logins(user_id, login_date) (deduplicated to one row per user per day), find users who logged in on at least 3 consecutive days. Return user_id and the start date of each streak.

WITH islands AS (
    SELECT user_id,
           login_date,
           login_date - ROW_NUMBER() OVER (
               PARTITION BY user_id ORDER BY login_date
           )::int AS grp
    FROM logins
)
SELECT user_id,
       MIN(login_date) AS streak_start,
       COUNT(*) AS streak_length
FROM islands
GROUP BY user_id, grp
HAVING COUNT(*) >= 3;

Why it matters: This is the classic gaps and islands problem disguised as a product question. The ROW_NUMBER minus date trick works because consecutive dates produce the same constant when you subtract a sequential integer. Non-consecutive dates break the constant, creating a new group. Interviewers love it because candidates who haven't seen the pattern struggle to invent it under pressure, and candidates who have seen it still need to explain why it works. The follow-up: "What if login_date has duplicates?" Your entire approach breaks. Deduplicate first or use DENSE_RANK instead of ROW_NUMBER.

9. ROW_NUMBER vs RANK vs DENSE_RANK

The question: Given sales(salesperson_id, region, revenue), rank each salesperson within their region by revenue. Show how results differ across all three ranking functions when two salespeople tie.

SELECT salesperson_id,
       region,
       revenue,
       ROW_NUMBER() OVER (PARTITION BY region ORDER BY revenue DESC) AS rn,
       RANK()       OVER (PARTITION BY region ORDER BY revenue DESC) AS rnk,
       DENSE_RANK() OVER (PARTITION BY region ORDER BY revenue DESC) AS drnk
FROM sales;
,  Ties at revenue=500: ROW_NUMBER gives 2,3 (arbitrary); RANK gives 2,2 then skips to 4; DENSE_RANK gives 2,2 then 3

Why it matters: 80% of data engineering interviews include window functions questions, yet candidates report feeling least prepared for them. The distinction is semantic, not performance; all three execute at similar speeds in modern query planners. ROW_NUMBER for arbitrary tie-breaking (deduplication). RANK when gaps after ties are acceptable (competition scoring). DENSE_RANK when you need continuous ranks. A real incident: a product ranking dashboard showed positions 1,2,3,4,5,6,6,8 because RANK skipped 7 after a tie. Leadership spent half a day troubleshooting before anyone realized the function was correct but the business needed DENSE_RANK. The choice isn't about data; it's about what the business question actually needs.

10. Running Total With Correct Window Frame

The question: Given transactions(account_id, txn_date, amount), compute a running balance per account ordered by transaction date. Then explain why LAST_VALUE often returns unexpected results.

SELECT account_id,
       txn_date,
       amount,
       SUM(amount) OVER (
           PARTITION BY account_id
           ORDER BY txn_date
           ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
       ) AS running_balance
FROM transactions;

Why it matters: The default window frame when ORDER BY is present is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, which treats ties as a group. ROWS treats each row individually. For running totals this distinction matters when two transactions share the same date. The buried edge case: LAST_VALUE without ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING returns the current row, not the last row in the partition. 70% of first attempts get this wrong. Interviewers test frame specifications because they separate candidates who memorized OVER(PARTITION BY...) from those who actually understand how window boundaries work.

11. Find the Gap in a Sequence

The question: Given seat_reservations(seat_number) containing occupied seats (integers, not necessarily consecutive), find all gaps (unreserved ranges). Return gap_start and gap_end.

WITH boundaries AS (
    SELECT seat_number,
           LEAD(seat_number) OVER (ORDER BY seat_number) AS next_seat
    FROM seat_reservations
)
SELECT seat_number + 1 AS gap_start,
       next_seat - 1    AS gap_end
FROM boundaries
WHERE next_seat - seat_number > 1;

Why it matters: Gaps and islands questions slow candidates down because they don't look like standard "join and group by" prompts. The business story sounds custom; the right answer takes a couple of structured steps. LEAD() compares each row to its successor; any difference greater than 1 is a gap. The interviewer will push on edge cases: what about the gap before the first seat? What about the gap after the last? Those require knowing the full domain (e.g., seats 1 through 100) and adding boundary rows. Pattern recognition, not syntax, is the bottleneck.

12. Sessionize an Event Stream

The question: Given page_views(user_id, event_time, page_url), assign a session_id to each event. A new session starts when the gap between consecutive events for the same user exceeds 30 minutes.

WITH flagged AS (
    SELECT *,
           CASE WHEN event_time - LAG(event_time) OVER (
               PARTITION BY user_id ORDER BY event_time
           ) > INTERVAL '30 minutes'
           THEN 1 ELSE 0 END AS new_session
    FROM page_views
),
sessioned AS (
    SELECT *,
           SUM(new_session) OVER (
               PARTITION BY user_id ORDER BY event_time
           ) AS session_id
    FROM flagged
)
SELECT user_id, event_time, page_url, session_id
FROM sessioned;

Why it matters: This is the hardest pattern most sql interview rounds test. It combines LAG for gap detection, CASE for flag generation, and cumulative SUM for group assignment; three window functions in one query. The first event per user has a NULL lag, which the CASE treats as 0 (no new session), which is correct because it belongs to session 0. If you don't think through that NULL explicitly, your session IDs are off by one. Interviewers also ask: "What if the 30-minute threshold should vary by user?" Now you need a join to a config table inside the CASE expression. That's where it gets real.

The tools change every 18 months. The problems don't change. Schema drift, late-arriving data, upstream teams breaking contracts without telling you. These are eternal. And so is SQL.

These twelve problems aren't a random sample. They're the patterns I've seen repeated across FAANG loops, fintech screens, and startup onsites for years. The syntax is the easy part; the hard part is understanding grain, execution order, and what happens when your data has NULLs, ties, or gaps you didn't expect. If you can solve all twelve cold, you're solid. If you want structured reps with graded feedback, datadriven.io is good for sql interview questions like these.

What's the one SQL problem you'd add to this list? The pattern that tripped you up in a real interview that none of the prep guides cover?