runtime
81 / 88

lesson 81 Warehouse & reporting projects · advanced

Quarantine bad rows & reconcile the batch

Separate invalid records and reconcile the whole batch.

the idea

Filtering bad rows is not enough. Keep a reject table with the source key, the raw value and a reason, and prove the batch reconciles: accepted plus rejected equals the source count, with no row in both. Classify each reject by one deterministic primary reason.

Dataset: Retail

The tables the challenges use, with their first 6 rows. Under each column name: the kind of value it holds, and which table it links to.

raw_dates2 columns · 584 rows
row_idnumber · unique idraw_datetext
613920111101
614020111101
614120111101
614220111101
614320111101
614420111101
row_idnumber · unique id
6139
raw_datetext
20111101
row_idnumber · unique id
6140
raw_datetext
20111101
row_idnumber · unique id
6141
raw_datetext
20111101
row_idnumber · unique id
6142
raw_datetext
20111101
row_idnumber · unique id
6143
raw_datetext
20111101
row_idnumber · unique id
6144
raw_datetext
20111101

first 6 of 584 rows · your queries use all of them

worked example

Run these steps in order to see the idea before you write your own query. The step marked “the pattern” is what the challenges ask for. Running the example does not count toward progress.

  1. Count source rows to reconcile. source_rows is the total from raw_dates—accepted plus rejected rows in your batch must equal this number.the pattern

    example.sql
    SELECT COUNT(*) AS source_rows
    FROM raw_dates;
  2. Classify rejects in fixed order. CASE checks missing first, then format, then calendar so each bad row gets exactly one primary reason.

    step-2.sql
    SELECT
      raw_date,
      CASE
        WHEN raw_date IS NULL THEN 'missing'
        WHEN raw_date NOT GLOB '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
          THEN 'format'
        ELSE 'eight digits'
      END AS first_check
    FROM raw_dates
    WHERE raw_date IS NULL OR length(raw_date) <> 8
    LIMIT 10;
  3. Verify calendar dates survive normalization. For well-formed eight-digit strings, normalized should match candidate—mismatch means the calendar is invalid.

    step-3.sql
    SELECT
      raw_date,
      substr(raw_date, 1, 4) || '-' || substr(raw_date, 5, 2) || '-' || substr(raw_date, 7, 2) AS candidate,
      date(substr(raw_date, 1, 4) || '-' || substr(raw_date, 5, 2) || '-' || substr(raw_date, 7, 2), '+0 days') AS normalized
    FROM raw_dates
    WHERE raw_date GLOB '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
    LIMIT 10;

common mistake

If a row can match two reasons, CASE must check them in a fixed order so each row gets exactly one.

challenge 1

Create TEMP table checked_dates (row_id, raw_date, clean_date under the lesson 79 rule) and TEMP table date_rejects (row_id, raw_date, reason) for rows with no clean_date, with reason 'missing', 'format' or 'calendar'.

Return row_id, raw_date and reason from date_rejects.

what to return

Columns
row_idraw_datereason in this order
Rows
any order
Also checked
TEMP / table changes from your script
challenge-1.sql
 
To master this lesson, solve both challenges without hints and pass the concept check. 3 of 3 to go.
Quarantine bad rows & reconcile the batch — Warehouse & reporting projects · Runtime