{
  "schema": "vedokrok.public-item.v1",
  "release_id": "MHC-RPUB-20260920-75ad787a",
  "url": "/knowledge/name-what-one-row-means-before-joining-two-tables",
  "id": "MHC-D-RESEARCH-0980",
  "version": "0.1.0",
  "title": "Name what one row means before joining two tables",
  "summary": "The join may be working perfectly on the wrong relationship.",
  "kind": "checklist",
  "body": "State the grain: what does one row represent in each input? Then specify how many matches are allowed for the chosen key. Check that expectation before accepting the joined result; do not remove duplicates afterward merely to recover a familiar row count.",
  "limits": [
    "A legitimate one-to-many join expands rows. Null-key behavior also differs between tools, so do not assume SQL and spreadsheet-like joins are identical."
  ],
  "topics": [
    "work-02-data-reconciliation"
  ],
  "intents": [],
  "source_ids": [
    "RS-F228187ED3C9FC8D"
  ],
  "evidence": [
    {
      "claim": "pandas can validate one-to-one, one-to-many or many-to-one merge keys; allowing many-to-many does not perform a uniqueness check.",
      "source_id": "RS-F228187ED3C9FC8D",
      "role": "supports",
      "note": "Key uniqueness is a structural property, not proof that the selected join represents the intended relationship.",
      "locator": "validate parameter"
    }
  ],
  "use_when": [
    "A merge produces plausible columns but unexpectedly more rows or larger totals."
  ],
  "avoid_when": [
    "A legitimate one-to-many join expands rows. Null-key behavior also differs between tools, so do not assume SQL and spreadsheet-like joins are identical."
  ],
  "example": "Joining sales lines to several historical customer versions by customer number alone multiplies each sale.",
  "check": "The observed match count agrees with the declared relationship, and exceptions have an explanation.",
  "checklist": [
    "Name the complete business key on each side, including relevant date or organizational scope.",
    "Check uniqueness on the side that is supposed to contain one match.",
    "Inspect unmatched keys and compare row counts and meaningful totals before and after the join."
  ],
  "sources": [
    {
      "id": "RS-F228187ED3C9FC8D",
      "title": "pandas.merge",
      "url": "https://pandas.pydata.org/docs/reference/api/pandas.merge.html"
    }
  ],
  "relations": [
    {
      "from": "MHC-D-RESEARCH-0980",
      "to": "MHC-D-RESEARCH-0981",
      "type": "useful_with",
      "url": "/knowledge/reconcile-what-is-missing-and-what-should-never-have-arrived"
    }
  ],
  "collections": [
    {
      "id": "RC-1B134BE48D7DF2A0",
      "title": "Keep the meaning intact when data moves",
      "url": "/collections/keep-the-meaning-intact-when-data-moves"
    }
  ]
}
