Alternate Patient Identities
Alternate Patient IDs are an approach to incorporating patient data from sources other than an EHR, such as patient rosters from payers. It supports treating roster-only patients as first-class citizens in Relevant. Concretely, this allows for targeting them in Outreach and including them in Quality Measures, without them having a chart in the EHR. In the rest of this article, we’ll use Partnership HealthPlan (PHP) as an example roster.
How are these patients represented in the database?
Before answering that, it’s helpful to know that patients in Relevant’s database have a unique, numeric id column (specifically a bigint type in PostgreSQL). Rosters may have their own unique id for each patient, but it’s not guaranteed to be usable as-is for a patient id in Relevant. For example it may be alphanumeric, or overlap with an id from the EHR. To work around this, we derive a unique value from the roster data and use that within Relevant. These are typically negative numbers, to avoid any potential overlap with ids from the EHR. We call these “derived ids”.
When a roster patient successfully matches with an EHR patient, we capture that match in the alternate_patient_identities table. Each record is a single match, with the patient_id column referring to the EHR id ( patients.id) and the alternate_id referring to the derived roster id. The data in this table will be persisted across pipeline runs; it’s a historical account of all roster matches. The associated patients record will have a data_source column representing that they are from both sources, e.g. a value of “ecw,php”.
When a roster patient does not successfully match an EHR patient, a record for that roster patient is created in the patients data element. The id for this patient will be the derived id, and its data_source column will be only the roster, e.g. “php”.
A PHP-only patient was contacted via Outreach and came in for a visit. What happens next?
Once the patient is in the EHR, the next pipeline run will match their PHP record to their EHR record. This will result in a change to their patients.id value - it will now be the value from the EHR. Their previous id value will be captured in the alternate_patient_identities table, and any Outreach messages that referred to it will be updated to refer to the new id.
What happens when a PHP patient no longer matches with an EHR patient?
When the pipeline runs, the EHR patient will no longer have the PHP id in its patients.alternate_ids column. The record in alternate_patient_identities will still exist and represents the historical match.
Broken matches can be queried with:
SELECT alternate_patient_identities.*
FROM alternate_patient_identities
WHERE NOT EXISTS (
SELECT
FROM patients
WHERE patients.id = alternate_patient_identities.patient_id
AND alternate_patient_identities.alternate_id IN (
SELECT jsonb_array_elements(alternate_ids -> 'php')::bigint
)
);
Why are PHP patients matching to different EHR patients?
If a PHP patient matches to different EHR patients day-to-day, this could be an indication that the matching process is unable to pick a single, suitable patient. This could be because the same patient has multiple charts in the EHR, or that multiple patients’ demographic information is so similar, there is no clear match.
To view records in this state, with the alternate id, previously matched patient id, and currently matched patient id, use this query:
WITH broken_matches AS (
SELECT *
FROM alternate_patient_identities
WHERE NOT EXISTS (
SELECT
FROM patients
WHERE patients.id = alternate_patient_identities.patient_id
AND alternate_patient_identities.alternate_id IN (
SELECT jsonb_array_elements(alternate_ids -> 'php')::bigint
)
)
)
SELECT broken_matches.alternate_id,
broken_matches.patient_id AS originally_matched_patient_id,
patients.id AS currently_matched_patient_id
FROM broken_matches
JOIN patients ON broken_matches.alternate_id IN (
SELECT jsonb_array_elements(patients.alternate_ids -> 'php')::bigint
);