Skip to content

Add relational2 dataset to A/B test the SATA option-as-answer representation#7

Open
jacobmpeters wants to merge 3 commits into
mainfrom
feature/sata-dual-representation
Open

Add relational2 dataset to A/B test the SATA option-as-answer representation#7
jacobmpeters wants to merge 3 commits into
mainfrom
feature/sata-dual-representation

Conversation

@jacobmpeters

Copy link
Copy Markdown
Contributor

Adds a second dataset, relational2, to evaluate the alternative Select-All-That-Apply representation against real data without disturbing relational.

sql/relational2/build_responses.sql builds relational2.responses as a controlled A/B copy of relational.responses (a transform, not a re-unpivot): SATA rows are remodeled option-as-answer (question ← parent, answer ← option, source_question ← NULL) and response_unique_id is recomputed via the UDF on the new fields. Non-SATA rows are byte-identical, so any difference is attributable only to the SATA remodel. Scope = SATA only (grids/MC untouched).

  • compare_with_relational.sql — quantifies the difference (rows, ids changed, id health); no verbatim values.
  • scripts/smoke_test_relational2.py — synthetic, passes (grain preserved; SATA remodeled; non-SATA + ids unchanged; SATA ids recomputed & differ; all ids in OMOP range).
  • docs/sata_representation.md rewritten around relational2, including the dim implication (SATA parents would move into the question dim on enrichment).
  • Removes the earlier v_responses_sata_v2 view + its smoke test (superseded).

Brings the branch up to main (UDF, response_unique_id on responses). No production data read.

Note: run sql/relational2/build_responses.sql after the relational pipeline; it depends on relational.responses, relational.question, and the relational.response_unique_id UDF.

jacobmpeters and others added 3 commits July 20, 2026 12:52
Supports BOTH Select-All-That-Apply representations until we decide:
- base `responses` fact stays as-is (legacy "option-as-question": each
  checked option is its own row, option = question_concept_id, parent =
  source_question_concept_id)
- new view `v_responses_sata_v2` presents "option-as-answer" (question =
  the SATA parent, chosen option = response_value_*), matching how
  single-select Multiple Choice is already modeled.

It's a pure relabeling view over `responses` — no data copied, fully
reversible via orig_* lineage columns + a `sata_remodeled` flag.

Scope = SATA only: grids are NOT remodeled (a grid sub-item is a genuinely
distinct question) and MC single-select is already option-as-answer. SATA is
identified by question_type LIKE '%select all that apply%' (isolated in one
CTE; depends on dictionary question_type quality — see the doc).

Downstream consumers (incl. the OMOP hash) choose a source by reading either
`responses` or `v_responses_sata_v2`. NOTE: SATA rows hash differently between
the two (3 of the 4 hashed fields move), so pick the representation before
freezing the hash contract.

Adds docs/sata_representation.md and a production-free smoke test that runs the
real view SQL in DuckDB (SATA remodeled; grid/MC/free-text unchanged; lossless).
Replaces the earlier in-place view approach with a second dataset, relational2,
so the alternative Select-All-That-Apply representation can be evaluated against
real data side-by-side with relational (which stays untouched).

- sql/relational2/build_responses.sql: creates the relational2 dataset and
  relational2.responses — a controlled A/B copy of relational.responses (a
  transform, not a re-unpivot) where SATA rows are remodeled option-as-answer
  (question <- parent, answer <- option, source_question <- NULL) and
  response_unique_id is RECOMPUTED via the UDF on the new fields. Non-SATA rows
  are byte-identical, so any downstream difference is attributable only to the
  SATA remodel. Scope = SATA only (grids/MC untouched).
- sql/relational2/compare_with_relational.sql: quantifies the difference
  (rows, ids changed, id health) — no verbatim values.
- scripts/smoke_test_relational2.py: synthetic test proving grain preserved,
  SATA remodeled, non-SATA + their ids unchanged, SATA ids recomputed & differ,
  all ids in OMOP range. Passes.
- docs/sata_representation.md rewritten around relational2 (incl. the dim
  implication: SATA parents would move into the question dim on enrichment).
- Remove the superseded v_responses_sata_v2 view + its smoke test.

Brings feature/sata-dual-representation up to main (UDF, response_unique_id on
responses) via merge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant