

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# SQL을 사용하여 HealthLake 데이터 쿼리
<a name="integrating-athena-query-sql"></a>

FHIR 데이터를 HealthLake 데이터 스토어로 가져오면 중첩된 JSON FHIR 데이터는 동시에 ETL 프로세스를 거치고 Amazon S3에 Apache Iceberg 오픈 테이블 형식으로 저장됩니다. HealthLake 데이터 스토어의 각 FHIR 리소스 유형은 Amazon Athena를 사용하여 쿼리할 수 있는 테이블로 변환됩니다. SQL 기반 쿼리를 사용하여 테이블을 개별적으로 또는 그룹으로 쿼리할 수 있습니다. 데이터 스토어의 구조로 인해 데이터를 Athena로 여러 데이터 유형으로 가져옵니다. 이러한 데이터 유형에 액세스할 수 있는 SQL 쿼리를 생성하는 방법에 대한 자세한 내용은 *Amazon Athena 사용 설명서*의 [복잡한 유형 및 중첩 구조가 있는 쿼리 배열](https://docs.aws.amazon.com/athena/latest/ug/rows-and-structs.html)을 참조하세요.

**참고**  
이 주제의 모든 예제에서는 Synthea를 사용하여 생성된 가상 데이터를 사용합니다. Synthea 데이터가 사전 로드된 데이터 스토어를 생성하는 방법에 대한 자세한 내용은 섹션을 참조하세요[HealthLake 데이터 스토어 생성](managing-data-stores-create.md).

리소스 유형의 각 요소에 대해 FHIR 사양은 카디널리티를 정의합니다. 요소의 카디널리티는이 요소가 나타날 수 있는 횟수의 하한과 상한을 정의합니다. SQL 쿼리를 생성할 때 이를 고려해야 합니다. 예를 들어 [리소스 유형: 환자](https://hl7.org/fhir/R4/patient.html)에서 몇 가지 요소를 살펴보겠습니다.
+ **요소: 이름** FHIR 사양은 카디널리티를 로 설정합니다`0..*`.

  요소는 배열로 캡처됩니다.

  ```
  [{
  	id = null,
  	extension = null,
  	use = official,
  	_use = null,
  	text = null,
  	_text = null,
  	family = Wolf938,
  	_family = null,
  	given = [Noel608],
  	_given = null,
  	prefix = null,
  	_prefix = null,
  	suffix = null,
  	_suffix = null,
  	period = null
  }]
  ```

  Athena에서 리소스 유형이 어떻게 수집되었는지 확인하려면 **테이블 및 뷰**에서 해당 유형을 검색합니다. 이 배열의 요소에 액세스하려면 점 표기법을 사용할 수 있습니다. 다음은 `given` 및의 값에 액세스하는 간단한 예제입니다`family`.

  ```
  SELECT
      name[1].given as FirstName,
      name[1].family as LastName
  FROM Patient
  ```
+ **요소: MaritalStatus** FHIR 사양은 카디널리티를 로 설정합니다`0..1`.

  이 요소는 JSON으로 캡처됩니다.

  ```
  {
  	id = null,
  	extension = null,
  	coding = [
  		{
  			id = null,
  			extension = null,
  			system = http: //terminology.hl7.org/CodeSystem/v3-MaritalStatus,
  				_system = null,
  			version = null,
  			_version = null,
  			code = S,
  			_code = null,
  			display = Never Married,
  			_display = null,
  			userSelected = null,
  			_userSelected = null
  		}
  
  	],
  	text = Never Married,
  	_text = null
  }
  ```

  Athena에서 리소스 유형이 어떻게 수집되었는지 확인하려면 **테이블 및 뷰**에서 해당 유형을 검색합니다. JSON의 키-값 페어에 액세스하려면 점 표기법을 사용할 수 있습니다. 배열이 아니기 때문에 배열 인덱스가 필요하지 않습니다. 다음은의 값에 액세스하는 간단한 예입니다`text`.

  ```
  SELECT
      maritalstatus.text as MaritalStatus
  FROM Patient
  ```

JSON 액세스 및 검색에 대한 자세한 내용은 *Athena 사용 설명서*의 [JSON 쿼리](https://docs.aws.amazon.com//athena/latest/ug/querying-JSON.html)를 참조하세요.

Athena Data Manipulation Language(DML) 쿼리 문은 Trino를 기반으로 합니다. Athena는 Trino의 모든 기능을 지원하지 않으며 *상당한* 차이가 있습니다. 자세한 내용은 *Amazon Athena 사용 설명서*의 [DML 쿼리, 함수 및 연산자를](https://docs.aws.amazon.com/athena/latest/ug/functions-operators-reference-section.html) 참조하세요.

또한 Athena는 HealthLake 데이터 스토어의 쿼리를 생성할 때 발생할 수 있는 여러 데이터 유형을 지원합니다. Athena의 데이터 유형에 대한 자세한 내용은 [ Amazon Athena 사용 설명서의 Amazon Athena의 데이터 유형을](https://docs.aws.amazon.com/athena/latest/ug/data-types.html) 참조하세요. *Amazon Athena *

Athena에서 SQL 쿼리가 작동하는 방식에 대한 자세한 내용은 [ Amazon Athena 사용 설명서의 Amazon Athena용 SQL 참조](https://docs.aws.amazon.com/athena/latest/ug/ddl-sql-reference.html)를 참조하세요. *Amazon Athena *

각 탭은 Athena를 사용하여 지정된 리소스 유형 및 관련 요소를 검색하는 방법의 예를 보여줍니다.

------
#### [ Element: Extension ]

요소는 데이터 스토어에서 사용자 지정 필드를 생성하는 데 `extension` 사용됩니다.

이 예제에서는 `Patient` 리소스 유형에 있는 `extension` 요소의 기능에 액세스하는 방법을 보여줍니다.

HealthLake 데이터 스토어를 Athena로 가져오면 리소스 유형의 요소가 다르게 구문 분석됩니다. 의 구조`element`는 가변적이므로 스키마에서 완전히 지정할 수 없습니다. 이러한 변동성을 처리하기 위해 배열 내의 요소는 문자열로 전달됩니다.

의 표 설명에서 로 `extension` 설명된 요소를 볼 수 있습니다. `array<string>`즉`Patient`, 인덱스 값을 사용하여 배열의 요소에 액세스할 수 있습니다. 그러나 문자열의 요소에 액세스하려면를 사용해야 합니다`json_extract`.

다음은 환자 테이블에 있는 `extension` 요소의 단일 항목입니다.

```
[{
		"valueString": "Kerry175 Cummerata161",
		"url": "http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName"
	},
	{
		"valueAddress": {
			"country": "DE",
			"city": "Hamburg",
			"state": "Hamburg"
		},
		"url": "http://hl7.org/fhir/StructureDefinition/patient-birthPlace"
	},
	{
		"valueDecimal": 0.0,
		"url": "http://synthetichealth.github.io/synthea/disability-adjusted-life-years"
	},
	{
		"valueDecimal": 5.0,
		"url": "http://synthetichealth.github.io/synthea/quality-adjusted-life-years"
	}
]
```

유효한 JSON이더라도 Athena는 이를 문자열로 취급합니다.

이 SQL 쿼리 예제에서는 `patient-mothersMaidenName` 및 `patient-birthPlace` 요소가 포함된 테이블을 생성하는 방법을 보여줍니다. 이러한 요소에 액세스하려면 다른 배열 인덱스 및를 사용해야 합니다. `json_extract.` 

```
SELECT
    extension[1],
    json_extract(extension[1], '$.valueString') AS MothersMaidenName,
    extension[2],
    json_extract(extension[2], '$.valueAddress.city') AS birthPlace
FROM patient
```

JSON과 관련된 쿼리에 대한 자세한 내용은 *Amazon Athena 사용 설명서*의 [JSON에서 데이터 추출](https://docs.aws.amazon.com/athena/latest/ug/extracting-data-from-JSON.html)을 참조하세요.

------
#### [ Element: birthDate (Age) ]

Age는 FHIR에서 환자 리소스 유형의 요소가 *아닙니다*. 다음은 연령을 기준으로 필터링하는 검색의 두 가지 예입니다.

수명은 요소가 아니므로 SQL 쿼리`birthDate`에를 사용합니다. 요소가 FHIR에 어떻게 수집되었는지 확인하려면 테이블 **및 뷰에서 테이블** 이름을 검색합니다. **문자열** 유형임을 알 수 있습니다.

**예제 1**: 연령 값 계산

이 샘플 SQL 쿼리에서는 내장 SQL 도구 `current_date` 및를 사용하여 이러한 구성 요소를 추출`year`합니다. 그런 다음 이를 빼서 환자의 실제 연령을 라는 열로 반환합니다`age`.

```
SELECT
	(year(current_date) - year(date(birthdate))) as age
FROM patient
```

**예제 2**: 이전에 태어났`2019-01-01`고 인 환자를 필터링합니다`male`.

SQL 쿼리는 `CAST` 함수를 사용하여 `birthDate` 요소를 유형으로 캐스팅하는 방법과 `WHERE` 절의 두 기준을 기반으로 필터링하는 `DATE`방법을 보여줍니다. 요소는 기본적으로 유형 **문자열**로 수집되므로 유형`CAST`으로 수집해야 합니다`DATE`. 그런 다음 `<` 연산자를 사용하여 다른 날짜인와 비교할 수 있습니다`2019-01-01`. 를 사용하여 `WHERE`절에 두 번째 기준을 추가할 `AND`수 있습니다.

```
SELECT birthdate
FROM patient
-- we convert birthdate (varchar) to date  > cast that as date too
WHERE CAST(birthdate AS DATE) < CAST('2019-01-01' AS DATE) AND gender = 'male'
```

------
#### [ Resource type: Location ]

이 예제는 도시 이름이 Attle™인 Location 리소스 유형 내 위치 검색을 보여줍니다.

```
SELECT *
FROM Location
WHERE address.city='ATTLEBORO'
LIMIT 10;
```

------
#### [ Element: Age ]

```
SELECT birthdate
FROM patient
-- we convert birthdate (varchar) to date  > cast that as date too
WHERE CAST(birthdate AS DATE) < CAST('2019-01-01' AS DATE) AND gender = 'male'
```

------
#### [ Resource type: Condition ]

리소스 유형 조건은 우려 수준으로 상승한 문제와 관련된 진단 데이터를 저장합니다. HealthLake의 통합 의료 자연어 처리(NLP)는 DocumentReference `Condition` 리소스 유형에 있는 세부 정보를 기반으로 *새* 리소스를 생성합니다. 새 리소스가 생성되면 HealthLake는 태그를 `SYSTEM_GENERATED` `meta` 요소에 추가합니다. 이 샘플 SQL 쿼리는 조건 테이블을 검색하고 결과가 제거된 `SYSTEM_GENERATED` 결과를 반환하는 방법을 보여줍니다.

HealthLake의 통합 자연어 처리(NLP)에 대한 자세한 내용은 섹션을 참조하세요[HealthLake용 통합 자연어 처리(NLP)](integrating-nlp.md).

```
SELECT *
FROM condition
WHERE meta.tag[1] is NULL
```

지정된 문자열 요소 내에서 검색하여 쿼리를 추가로 필터링할 수도 있습니다. `modifierextension` 요소에는 조건 세트를 생성하는 데 사용된 `DocumentReference` 리소스에 대한 세부 정보가 포함되어 있습니다. 다시 말하지만 `json_extract`를 사용하여 Athena로 문자열로 가져온 중첩된 JSON 요소에 액세스해야 합니다.

이 샘플 SQL 쿼리는 특정를 기반으로 생성된 모든를 검색`Condition`하는 방법을 보여줍니다`DocumentReference`. `CAST`를 사용하여를 `LIKE` 비교할 수 있도록 JSON 요소를 문자열로 설정합니다.

```
SELECT
    meta.tag[1].display as SystemGenerated,
    json_extract(modifierextension[4], '$.valueReference.reference') as DocumentReference
FROM condition
WHERE meta.tag[1].display = 'SYSTEM_GENERATED'

AND CAST(json_extract(modifierextension[4], '$.valueReference.reference') as VARCHAR) LIKE '%DocumentReference/67aa0278-8111-40d0-8adc-43055eb9d18d%'
```

------
#### [ Resource type: Observation ]

리소스 유형인 관찰은 환자, 디바이스 또는 기타 주제에 대한 측정값과 간단한 어설션을 저장합니다. HealthLake의 통합 자연어 처리(NLP)는 `Observation` 리소스에 있는 세부 정보를 기반으로 *새* `DocumentReference` 리소스를 생성합니다. 이 샘플 SQL 쿼리에는 `WHERE meta.tag[1] is NULL` 주석이 추가되어 `SYSTEM_GENERATED` 결과가 포함됩니다.

```
SELECT valueCodeableConcept.coding[1].code
FROM Observation
WHERE  valueCodeableConcept.coding[1].code = '266919005'
-- WHERE meta.tag[1] is NULL
```

이 열은 로 가져왔습니다[https://iceberg.apache.org/spec/#schemas-and-data-types](https://iceberg.apache.org/spec/#schemas-and-data-types). 따라서 점 표기법을 사용하여 내부 요소에 액세스할 수 있습니다.

------
#### [ Resource type: MedicationStatement ]

MedicationStatement는 환자가 사용했거나 사용 중이거나 향후 사용할 약에 대한 세부 정보를 저장하는 데 사용할 수 있는 FHIR 리소스 유형입니다. HealthLake의 통합 의료 자연어 처리(NLP)는 DocumentReference 리소스 유형에 있는 문서를 기반으로 새 MedicationStatement 리소스를 생성합니다. 새 리소스가 생성되면 HealthLake는 태그를 `SYSTEM_GENERATED` `meta` 요소에 추가합니다. 이 샘플 SQL 쿼리는 식별자를 사용하여 단일 환자를 기준으로 필터링하고 HealthLake의 통합 NLP에서 추가한 리소스를 찾는 쿼리를 생성하는 방법을 보여줍니다.

```
SELECT *
FROM medicationstatement
WHERE meta.tag[1].display = 'SYSTEM_GENERATED' AND subject.reference = 'Patient/0679b7b7-937d-488a-b48d-6315b8e7003b';
```

HealthLake의 통합 자연어 처리(NLP)에 대한 자세한 내용은 섹션을 참조하세요[HealthLake용 통합 자연어 처리(NLP)](integrating-nlp.md).

------