Chuyển đến nội dung chính

Lesson 11: OBSERVATION — General clinical events

The OBSERVATION table records clinical events that are not part of Condition, Drug, Procedure, or Measurement. Medical history, lifestyle, allergies, family history, new observation_event_id CDM 5.4.

🏗️ Architecture — Lesson 11 OBSERVATION Summary of clinical events OMOP CDM 5.4 for Beginners — Understand A to Z Part 4: Expanded clinical table xdev.asia

Introduction

OBSERVATION is a "catch-all" table — the place to store any clinical events that do not match Condition, Drug, Procedure, or Measurement. Medical history, lifestyle (smoking, drinking), allergies, family history, marital status — it's all here.


1. Table structure

ColumnTypeRequiredDescription
observation_idINTEGER✅ PKUnique ID
person_idINTEGER✅ FKPatients
observation_concept_idINTEGER✅Standard Concept
observation_dateDATE✅Record date
observation_datetimeDATETIMEDate and time
observation_type_concept_idINTEGER✅Data source
value_as_numberFLOATNumeric value
value_as_stringVARCHAR(60)Text value
value_as_concept_idINTEGERCategory Value
qualifier_concept_idINTEGERAdditional context
unit_concept_idINTEGERUnit
provider_idINTEGERFKProvider records
visit_occurrence_idINTEGERFKRelated Visit
visit_detail_idINTEGERFKVisit details
observation_source_valueVARCHAR(50)Original code
observation_source_concept_idINTEGEROriginal concept
unit_source_valueVARCHAR(50)Original unit
qualifier_source_valueVARCHAR(50)Original Qualifier
value_as_datetimeDATETIME⭐ CDM 5.4
observation_event_idBIGINT⭐ CDM 5.4
obs_event_field_concept_idINTEGER⭐ CDM 5.4

2. What to save in OBSERVATION?

2.1. List of use cases

Use casesobservation_concept_idvalueExample
Smoking4275495 (Tobacco smoking)value_as_concept_id4298794 (Current smoker)
Allergy439224 (Allergy)value_as_concept_idDrug/food concept
Family history4167217 (Family history of)value_as_concept_idDisease concept
Marital status4053609 (Marital status)value_as_concept_id4338692 (Married)
Blood type4041671 (Blood type)value_as_concept_id36308332 (Type O)
Medical history4214956 (History of) + condition conceptvalue_as_concept_id
Pregnancy4299535 (Pregnancy)value_as_concept_id
Profession4019962 (Occupation)value_as_string"Teacher"

2.2. OBSERVATION vs CONDITION — When to save where?

DataTableExplanation
"Patients with type 2 diabetes"CONDITIONActive disease
"Family history of diabetes"OBSERVATIONFamily history
"Patient had hepatitis B (recovered)"OBSERVATIONHistory of
"Penicillin Allergy"OBSERVATIONAllergy
"Patient has smoked for 20 years"OBSERVATIONLifestyle
"Fever 38.5°C"MEASUREMENTHas measurement value

3. Detailed example

3.1. Smoking

INSERT INTO observation (
    observation_id, person_id, observation_concept_id,
    observation_date, observation_type_concept_id,
    value_as_concept_id,
    observation_source_value
) VALUES (
    130001, 100001,
    4275495,                     -- Tobacco smoking behavior
    '2024-06-15', 32817,
    4298794,                     -- Current every day smoker
    'SMOKING_STATUS'
);

3.2. Drug allergy

-- Dị ứng Penicillin
INSERT INTO observation (
    observation_id, person_id, observation_concept_id,
    observation_date, observation_type_concept_id,
    value_as_concept_id,
    qualifier_concept_id,
    observation_source_value
) VALUES (
    130002, 100001,
    439224,                      -- Allergy to substance
    '2024-06-15', 32817,
    1713332,                     -- Penicillin (RxNorm ingredient)
    4129512,                     -- Severe (qualifier)
    'ALLERGY_PENICILLIN'
);

3.3. Family history

-- Mẹ bị ung thư vú
INSERT INTO observation (
    observation_id, person_id, observation_concept_id,
    observation_date, observation_type_concept_id,
    value_as_concept_id,
    qualifier_concept_id,
    observation_source_value
) VALUES (
    130003, 100001,
    4167217,                     -- Family history of clinical finding
    '2024-06-15', 32817,
    4112853,                     -- Malignant neoplasm of breast
    4166847,                     -- Mother (qualifier)
    'FHX_BREAST_CANCER_MOTHER'
);

4. observation_event_id — CDM 5.4

Similar to measurement_event_id, allows linking observations to other events.

-- Ghi nhận: "Lý do nhập viện: Đau ngực"
-- Liên kết với visit_occurrence_id = 50001
INSERT INTO observation (
    observation_id, person_id, observation_concept_id,
    observation_date, observation_type_concept_id,
    value_as_concept_id,
    observation_event_id,
    obs_event_field_concept_id
) VALUES (
    130004, 100001,
    4148832,                     -- Chief complaint
    '2024-06-15', 32817,
    77670,                       -- Chest pain
    50001,                       -- visit_occurrence_id
    1147082                      -- Field = visit_occurrence.visit_occurrence_id
);

5. qualifier_concept_id — Adds context

Concept IDQualifierUsed for
4129512SevereSeverity level
4148136MildMild level
4129511ModerateModerate level
4166847MotherFamily relationships
4166848FatherFamily relationships
4192403SiblingBrother/sister
4167233First degree relative1st degree relative

6. VN data ETL

-- Tiền sử từ HIS
SELECT
    ROW_NUMBER() OVER() AS observation_id,
    pm.person_id,
    COALESCE(stcm.target_concept_id, 0) AS observation_concept_id,
    ts.ngay_ghinhan AS observation_date,
    32817 AS observation_type_concept_id,
    -- Map giá trị
    CASE ts.loai_tiensu
        WHEN 'HUT_THUOC' THEN
            CASE ts.gia_tri
                WHEN 'CO' THEN 4298794     -- Current smoker
                WHEN 'DA_BO' THEN 4144272  -- Former smoker
                WHEN 'KHONG' THEN 4144273  -- Never smoker
            END
        WHEN 'DI_UNG' THEN
            COALESCE(stcm_drug.target_concept_id, 0)
    END AS value_as_concept_id,
    ts.mo_ta AS value_as_string,
    ts.ma_tiensu AS observation_source_value
FROM tiensu_his ts
JOIN person_mapping pm ON ts.ma_bn = pm.source_id
LEFT JOIN source_to_concept_map stcm
    ON ts.loai_tiensu = stcm.source_code
    AND stcm.source_vocabulary_id = 'VN_OBS_TYPE'
LEFT JOIN source_to_concept_map stcm_drug
    ON ts.gia_tri = stcm_drug.source_code
    AND stcm_drug.source_vocabulary_id = 'VN_DRUG';

7. SQL analysis

-- Tỉ lệ hút thuốc theo giới tính
SELECT
    g.concept_name AS gender,
    s.concept_name AS smoking_status,
    COUNT(DISTINCT o.person_id) AS patients
FROM observation o
JOIN person p ON o.person_id = p.person_id
JOIN concept g ON p.gender_concept_id = g.concept_id
JOIN concept s ON o.value_as_concept_id = s.concept_id
WHERE o.observation_concept_id = 4275495  -- Tobacco smoking
GROUP BY g.concept_name, s.concept_name
ORDER BY g.concept_name, patients DESC;

-- Top dị ứng thuốc
SELECT
    c.concept_name AS allergen,
    COUNT(DISTINCT o.person_id) AS patients
FROM observation o
JOIN concept c ON o.value_as_concept_id = c.concept_id
WHERE o.observation_concept_id = 439224  -- Allergy
GROUP BY c.concept_name
ORDER BY patients DESC
LIMIT 10;

Summary

  1. OBSERVATION = "catch-all" table for data that is not part of a specialized table
  2. Main use cases: smoking, allergies, family history, lifestyle, marriage
  3. qualifier_concept_id adds context (level, relationship)
  4. CDM 5.4: observation_event_id associated with another event
  5. Domain routing decides Observation vs Condition vs Measurement

Next article: DEVICE_EXPOSURE, SPECIMEN & NOTE — medical devices, specimens, and clinical notes.


References