AQL support for demographic queries

Queries using SYSTEM

As demographic data does not reside inside EHRs, there should be an upper structure which would be usable in those queries that combines EHRs with demographic data. This is especially needed for those settings facilitating querying across multi-tenant’s data, or when EHRs are clustered on the server side.

https://openehr.atlassian.net/wiki/spaces/spec/pages/1915879489 is already described on another page. A typical query using system may look like:

SELECT s/uid, s/name, e/ehr_id/value, c/context/start_time FROM SYSTEM s CONTAINS EHR e CONTAINS COMPOSITION c

When SYSTEM is omitted, the engine will query for data in all selected EHRs will use all available systems, like it is already supposed to work in standard AQL:

SELECT e/ehr_id/value, c/context/start_time FROM EHR e CONTAINS COMPOSITION c

And if the query addresses Demographic it would be query for data in all available systems:

SELECT p/uid/value, pid/item/value FROM PERSON p [openEHR-DEMOGRAPHIC-PERSON.person.v2] CONTAINS PARTY_IDENTITY pid [openEHR-DEMOGRAPHIC-PARTY_IDENTITY.person_name.v2]

One aspect to consider is that SYSTEM does not actually “contains” EHRs, but it is the EHR that referrers to the owning system. For this matter, if we would like to consider a new keyword (an AQL syntax change), for instance WRAPS, we could have:
FROM SYSTEM s WRAPS (EHR e CONTAINS COMPOSITION c)

Introducing SYSTEM, allows the use of EHR data next to Demographic data inside same system:

or, with more complexity, using an fictive ENCRYPT() function that matches EHR with ACTOR in a environment that supports Master Patient Indexes:

Querying for demographic data

The following will retrieve only demographic data, showing example on various CONTAINS use cases:

Querying using relations

Another important use-case is when querying demographic data of actors that matches certain relationship condition. En example would be “Retrieve all Patient’s data (uid, name, age, gender) that are belonging to a specific Care Group X (relation type = 'patientOf').

Relations are store as PARTY_RELATIONSHIP instances, referred by ACTORS above, but they are not used explicitly in the query. The IS_RELATED() function will have to solve the query constrain by using those referred PARTY_RELATIONSHIP. Another variant would be to also add PARTY_RELATIONHIP in the FROM section: