Skip to the page
Tecyfy

Data engineering in the AI era · intermediate · About 10 minutes

The daily sales total that grows after midnight

Monday's sales on the dashboard say $412,600. Finance runs the same query on Thursday and gets $426,600. Nobody changed the data, and both numbers are right for the moment they were taken.

You own the nightly job that builds the daily sales table for 140 shops.

What happened

Every night at 00:30 a job builds daily_sales for the day that just ended. It reads the sales events with that day's sold_at date, sums them per shop and overwrites that day's row. The dashboard and the weekly report read daily_sales.

On Thursday, finance ran the same sum over the raw events for Monday and got $14,000 more than the dashboard shows. They ask which number is wrong, and why the dashboard never changed.

The incident is made up. How things work in it is real, with sources at the end.

The evidence

Everything you need is here. Read it before you decide.

01Monday's sales, summed from the raw events at different times(Table)
Summed atTotal for MondayShare of the final total
Tue 00:30 (the nightly job)$412,60096.6%
Wed 00:30$423,70099.2%
Thu 10:00 (finance)$426,60099.9%
Fri 00:30$427,100100.0%
02How the shops send sales(Note)

The till app keeps each sale when the shop's connection drops and sends it when the connection returns. Every event has sold_at, the time of the sale, and received_at, the time it reached the warehouse.

03Monday's latest arrivals(Table)
Shopsold_atreceived_atAmount
S-114Mon 18:42Tue 07:15$1,320
S-087Mon 11:05Wed 14:30$2,940
S-031Mon 20:10Thu 09:12$880
04The nightly job(Code)
-- runs at 00:30 for the day that just ended
insert overwrite daily_sales partition (sale_date = '{{ ds }}')
select shop_id, sum(amount) as sales
from sales_events
where date(sold_at) = '{{ ds }}'
group by shop_id;

Your decisions

Decision 1 of 3

  1. Decision 1

    Why do the dashboard and finance disagree?

The ideas behind it