Practical preparation / reliable data
Data engineering interviews: SQL, event pipelines and trustworthy metrics
Practice the path from raw events to a metric someone can trust. Work through duplicate deliveries, late payments, daily revenue, safe backfills and data-quality checks with an original fixture, SQL and failure scenarios.
- Define
- Grain + business meaning
- Challenge
- Duplicates + late data
- Prove
- Reconciliation + replay

Preparation map
Four moves before the interview
- 1
Define the dataset
Name the business question, row grain, identities, timezone and freshness target.
- 2
Choose the data path
Make ingestion, retention, transformation and publication boundaries visible.
- 3
Handle corrections
Separate redelivery, changed events, late arrival and a deliberate historical replay.
- 4
Verify the output
Use known totals, quality checks, ownership and a safe partition-publishing policy.

01 / FIELD NOTES
Prepare for the data role's actual deliverables
Analytics engineering, pipeline engineering, platform work and streaming systems share vocabulary but emphasize different decisions. Begin with the dataset or service the vacancy asks you to own.
- For an analytics role, prepare SQL, model grain, joins, metric definitions and stakeholder reconciliation. For ingestion or platform work, add source contracts, replay, deployment and failure recovery. For streaming work, practice ordering, event time, state and corrections.
- Ask whether the round includes a live SQL environment, a take-home pipeline or architecture discussion. Rehearse with a small inspectable fixture in a familiar tool. Do not spend the entire round configuring infrastructure when a query and clear assumptions can demonstrate the decision.
- Choose an honest evidence pack: a dataset definition, an executable transformation, a test that caught a defect and a recovery note. Identify synthetic rows and explain why they exercise a risk; do not present a toy dataset as production-scale proof.
- Use level-appropriate depth. A junior candidate can demonstrate correct SQL and careful checks; a senior candidate should also explain ownership, schema migration, operational costs, recovery objectives and how the business learns that a metric was corrected.
02 / FIELD NOTES
State the grain before writing SQL
A metric can be syntactically valid and still answer the wrong question. Define what one row means, which events count and when the result becomes publishable.
- For daily net revenue, specify whether you mean cash received, invoiced amount or another accounting definition. In the practice case, payments and refunds are signed event amounts assigned to their UTC event day. It is not a universal finance rule.
- Name the raw delivery grain separately from the business-event grain. Two deliveries of e-1 are not two payments. Include tenant identity in the event key, and distinguish a reused event ID with conflicting content from an identical redelivery.
- Define money units and currency. Use integer minor units or an appropriate decimal type rather than binary floating point. Keep different currencies separate unless the exercise supplies an explicit conversion rule, rate source and valuation time.
- Specify event time, ingestion time and reporting timezone. A payment arriving tomorrow may belong to yesterday's event-day total. Make the provisional/final status visible and choose how users will discover that a historical number changed.
- Document dimensions and join cardinality. If one order joins to three lines, summing the order total after that join triples it. Aggregate at the correct grain or use the correct line-level measure before joining to another many-row relation.
03 / FIELD NOTES
Make the query explain its own correctness
Use a small fixture with known outputs first. Then reason about the plan and the work required on the target database. Familiar syntax does not establish a correct business model.
- Write the expected rows on paper: which identities survive, how nulls behave and what should happen for a customer with no events. Use LEFT JOIN when missing activity must remain visible, and check whether a later WHERE clause accidentally removes those rows.
- For window-function deduplication, partition by the agreed event identity and provide deterministic ordering. The fixture below uses ingestion time plus unique source offset for identical deliveries. Production conflicts need a business rule or quarantine rather than an arbitrary winner.
- Compare counts and sums before and after each transformation. A smaller row count can be correct deduplication or accidental loss. Explain the expected difference using stable identities instead of celebrating any reduction as an improvement.
- Inspect a representative execution plan. Name the partitions scanned, join work, grouping and sort cost. Avoid selecting wide payloads unnecessarily. Check whether filters permit partition pruning and whether one heavily skewed key dominates a worker.
- Keep correctness checks when optimizing. Replacing a full calculation with an incremental one requires an explicit change boundary and correction policy. A faster result that cannot account for a late refund answers a different question.
04 / FIELD NOTES
Separate ingestion progress from trustworthy publication
Sketch the data path as a series of owned boundaries. For each one, explain durable input, replay identity, output and what survives a process crash.
- Retain raw input with provenance and an appropriate access and retention policy. Store event identity, source position, schema version and arrival metadata. Restrict sensitive fields and define deletion behavior; 'raw' does not mean every personal field must live forever.
- Choose batch or streaming from the consumer's latency need. A daily dashboard may be served by a bounded scheduled transform; a fraud decision may require a continuously updated path. State the operating cost and recovery complexity of the choice.
- Describe delivery guarantees at their actual boundary. Kafka can coordinate transactional processing within its supported scope; writing to an external destination requires coordinating progress with that destination. Naming a broker does not make every side effect exactly once.
- For a destination table, prefer a stable upsert identity or a validated partition replacement over unconditional append on replay. Explain when a consumer position is recorded relative to its output and what happens if a crash falls between them.
- Distinguish orchestration success from data correctness. A green task means its execution completed under that tool's rules. The published dataset still needs freshness, completeness and reconciliation checks before a consumer treats it as reliable.
05 / FIELD NOTES
Late events, schema changes and backfills need a policy
Corrections are normal in a data system. Define what can change and how to recover a known version before building an incremental pipeline.
- An event-time watermark estimates how far arrivals have progressed. It is not proof that every event exists. Choose allowed lateness and output triggers from the business tolerance; define an explicit correction route for records arriving outside that window.
- For the example, a late payment belongs to its original event day. Recompute that affected day from retained deduplicated input, compare the result with a known ledger and replace the published partition. Do not add the entire recomputed total onto the old total.
- A backfill has a bounded interval, a transform version, an owner and an output plan. Dry-run row counts, restrict concurrency, account for live writers and publish from staging only after verification. Preserve the previous version or a repeatable rollback path.
- For a schema change, distinguish additive nullable fields from renamed, removed or semantically changed fields. Test old and new producers together. Keep incompatible records in a visible quarantine with replay instructions instead of silently dropping them.
- Define what deletion or corrected business facts mean downstream. A tombstone, cancellation or changed amount may require updates to more than today's partition. Track lineage so the owner can identify affected aggregates and communicate corrections.
06 / FIELD NOTES
Turn data quality into a release decision
The useful question is which consumer decision becomes unsafe when a check fails. Choose tests that defend the dataset's definition and a response proportional to the impact.
- Start with schema and grain checks: required identities, accepted event types, unique business keys, valid timestamps and allowed value ranges. A test should expose the offending records and owner so a failure can lead to action.
- Add reconciliation: distinct source events versus accepted plus quarantined events, signed ledger amounts versus aggregated totals, and expected versus observed partitions. Keep the denominator and time interval explicit; one global success percentage can hide a missing customer.
- Monitor freshness and volume with context. A quiet weekend and a stalled ingestion task can both reduce rows. Combine source progress, arrival delay and historical patterns; define when to warn, block publication or serve the last validated snapshot.
- Test a duplicate, late record, null join key, refund, empty day, schema mismatch and a rerun over the same input. Confirm the expected output for each. For production claims, exercise the target storage engine and crash boundary in addition to the small SQL fixture.
- Rehearse a 45-minute round: clarify definition for 7 minutes, build and explain the query for 15, challenge corrections for 13 and summarize validation and handoff for 10. This is a practice schedule; your recruiter determines the actual format.
Worked engineering case
Six deliveries. Four events. Two correct daily totals.
An illustrative merchant receives payment and refund events. The transport can redeliver an event, and a payment made on October 10 may arrive on October 11. A dashboard must show net revenue by the event's UTC day, using signed integer cents.
Scope and assumptions: The producer guarantees stable (tenant_id, event_id) identities; duplicate deliveries have identical business fields. A reused ID with changed content is quarantined instead of silently chosen. Times are normalized UTC strings in this tiny SQL fixture; production should use appropriate typed timestamps and an explicit reporting timezone.
- Step 1
Keep raw events
Persist identity, event time and arrival provenance.
- Step 2
Deduplicate
One business event per tenant + event ID.
- Step 3
Group by event day
Attribute late payments to the day they occurred.
- Step 4
Reconcile + publish
Compare totals, then replace the affected partition.
| Event ID | Event day · UTC | Arrival day · UTC | Signed cents | Treatment |
|---|---|---|---|---|
| e-1 | Oct 10 | Oct 10 | +4200 | Keep |
| e-1 | Oct 10 | Oct 10 | +4200 | Duplicate delivery |
| e-2 | Oct 10 | Oct 11 | +2500 | Keep · late event |
| e-3 | Oct 11 | Oct 11 | −700 | Keep · refund |
| e-4 | Oct 11 | Oct 11 | +1800 | Keep |
| e-4 | Oct 11 | Oct 11 | +1800 | Duplicate delivery |
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY tenant_id, event_id
ORDER BY ingested_at, source_offset
) AS delivery_number
FROM raw_events
)
SELECT tenant_id,
substr(event_time, 1, 10) AS event_day,
SUM(amount_cents) AS net_cents
FROM ranked
WHERE delivery_number = 1
GROUP BY tenant_id, substr(event_time, 1, 10)
ORDER BY tenant_id, event_day;The unique ingestion offset breaks ties between identical deliveries. After the producer-content check, retain one delivery per event identity, then aggregate by event day. Expected net_cents: October 10 = 6700; October 11 = 1100. The query recomputes from retained raw input; it does not implement a streaming watermark or write the destination table.
Prove the result
- Before e-2 arrives, October 10 is provisional at 4200 cents. After its arrival, recompute October 10 to 6700; do not assign it to October 11.
- Replay all six deliveries. Keep four distinct events and totals 6700 / 1100. An append-only daily-total update would incorrectly add revenue again.
- Add the same event ID for another tenant and keep both. Change the amount on an existing ID and quarantine that conflict before aggregation.
- Reconcile the kept ledger: 4200 + 2500 − 700 + 1800 = 7800 cents, equal to 6700 + 1100. Publish validated partitions atomically and retain the prior version for recovery.
A correct total has a definition, a grain, stable identities and a correction policy. A watermark estimates arrival progress; it cannot prove that every business event has arrived. Retained raw data and reconciliation make the calculation explainable.
Original practice bank
Three tasks to work through aloud
These are ApplyDjinn practice prompts, not questions obtained from an employer. Use them to rehearse the reasoning and verification expected for the role.
Exercise 1
Daily revenue with redelivery
Prompt: Use the six-delivery fixture below to produce daily net revenue by event day. Explain why arrival-day grouping and unconditional summing both fail.
Approach: Define signed cents and UTC event day. Validate stable identities and duplicate-content equality; deduplicate by tenant plus event ID, then group the kept ledger. Compare with hand-calculated totals.
Test: Require 6700 cents on October 10, 1100 on October 11 and 7800 overall. Replay input without changing the totals; isolate a changed payload under an existing ID and a same-ID event from another tenant.
Follow-up: How would you update a published October 10 partition after its lateness window has closed?
Exercise 2
A join that doubles revenue
Prompt: An order fact joins to line items and campaign touches. Revenue suddenly doubles after adding the campaign table. Investigate without adding DISTINCT until the number looks right.
Approach: Name the grain and cardinality of each relation, inspect one affected order and count rows after each join. Choose an explicit attribution rule or aggregate each relation to a compatible grain before joining.
Test: Use an order with two lines and three touches, an order with no campaign and a refund. Assert the defined measure and ensure the fix does not drop unmatched orders or hide legitimate equal values.
Follow-up: What changes if the business wants multi-touch attribution instead of one campaign per order?
Exercise 3
Safe historical correction
Prompt: A transform misclassified refunds for the last 30 days. Fix the history while live data keeps arriving and downstream users rely on the dashboard.
Approach: Identify affected partitions and the correct definition. Run a versioned backfill into staging, bound resource use, reconcile the repaired ledger and coordinate an atomic publication boundary with the live path.
Test: Retry the backfill, fail midway, overlap with live input and compare pre/post totals. Keep the old validated version available and tell consumers which intervals changed.
Follow-up: What evidence lets you publish part of the interval while another partition is still under investigation?
Source check
Primary sources
These primary materials support the published process or technical context. The exercises and preparation framework are original editorial material; confirm your own interview format with the recruiter.
- Window functions ↗PostgreSQL
- Using EXPLAIN ↗PostgreSQL
- Message delivery semantics ↗Apache Kafka
- Watermarks, late data and triggers ↗Apache Beam
- Backfill controls ↗Apache Airflow
- Data tests ↗dbt
Continue preparing with evidence
Choose a current role, map its requirements to projects you can defend, then practice the round your recruiter actually scheduled.