SELECT 명령
SELECT 명령
S3 Select에서 객체를 조회할 때 쓰는 SQL은 모두 SELECT 명령 하나로 시작해요. SELECT 목록, FROM절, WHERE절, LIMIT절로 구성된 표준 SQL 형태를 지원하며, JSON 객체를 다룰 때 쓰는 경로 표현식과 속성 접근 방식까지 명령별로 정리해 드릴게요.
출처: 문서
본문
중요 Amazon S3 Select는 더 이상 신규 고객에게 제공되지 않아요. 기존 Amazon S3 Select 고객은 평소처럼 기능을 계속 사용할 수 있어요.
Amazon S3 Select는 SELECT SQL 명령만 지원해요. SELECT에 대해 다음 ANSI 표준 절이 지원돼요.
- SELECT 목록
- FROM 절
- WHERE 절
- LIMIT 절
참고 Amazon S3 Select 쿼리는 현재 서브쿼리(subquery)나 조인(join)을 지원하지 않아요.
SELECT 목록
SELECT 목록은 쿼리가 반환하려는 열, 함수, 표현식을 이름으로 지정해요. 이 목록이 쿼리의 출력을 나타내요.
SELECT *
SELECT projection1 AS column_alias_1, projection2 AS column_alias_2
*(별표)가 있는 첫 번째 형태의 SELECT는 WHERE 절을 통과한 모든 행을 그대로 반환해요. 두 번째 형태의 SELECT는 각 열에 대해 사용자 정의 출력 스칼라 표현식 projection1과 projection2가 있는 행을 만들어요.
FROM 절
Amazon S3 Select는 다음 형태의 FROM 절을 지원해요.
FROM table_name
FROM table_name alias
FROM table_name AS alias
각 FROM 절 형태에서 table_name은 조회되는 S3Object예요. 전통적인 관계형 데이터베이스를 써 온 사용자는 이것을 한 테이블에 대한 여러 뷰(view)를 담는 데이터베이스 스키마로 생각할 수 있어요.
표준 SQL에 따라 FROM 절은 행을 만들고, WHERE 절에서 그 행을 필터링하며 SELECT 목록에서 투영(project)해요.
Amazon S3 Select에 저장된 JSON 객체의 경우 다음 형태의 FROM 절도 사용할 수 있어요.
FROM S3Object[*].path
FROM S3Object[*].path alias
FROM S3Object[*].path AS alias
이 형태의 FROM 절을 사용하면 JSON 객체 안의 배열이나 객체에서 선택할 수 있어요. path는 다음 형태 중 하나로 지정할 수 있어요.
- 이름으로(객체에서):
.name또는['name'] - 인덱스로(배열에서):
[index] - 와일드카드 문자로(객체에서):
.* - 와일드카드 문자로(배열에서):
[*]
참고
- 이 형태의 FROM 절은 JSON 객체에서만 작동해요.
- 와일드카드 문자는 항상 레코드를 하나 이상 내보내요. 일치하는 레코드가 없으면 Amazon S3 Select는
MISSING값을 내보내요. 출력 직렬화 단계(쿼리 실행 완료 후)에서 Amazon S3 Select는MISSING값을 빈 레코드로 바꿔요.- 집계 함수(
AVG,COUNT,MAX,MIN,SUM)는MISSING값을 건너뛰어요.- 와일드카드 문자를 사용할 때 별칭을 제공하지 않으면 경로의 마지막 요소로 행을 참조할 수 있어요. 예를 들어 책 목록에서 모든 가격을 선택하려면
SELECT price FROM S3Object[*].books[*].price쿼리를 쓰면 돼요. 경로가 이름 대신 와일드카드 문자로 끝나면_1값을 사용해 행을 참조할 수 있어요. 예를 들어SELECT price FROM S3Object[*].books[*].price대신SELECT _1.price FROM S3Object[*].books[*]쿼리를 쓸 수 있어요.- Amazon S3 Select는 JSON 문서를 항상 루트 수준 값의 배열로 취급해요. 따라서 조회하는 JSON 객체에 루트 요소가 하나만 있어도 FROM 절은
S3Object[*]로 시작해야 해요. 다만 호환성 때문에 경로를 포함하지 않으면 Amazon S3 Select는 와일드카드 문자를 생략할 수 있게 해 줘요. 따라서 완전한 절FROM S3Object는FROM S3Object[*] AS S3Object와 동등해요. 경로를 포함하면 와일드카드 문자도 사용해야 해요. 그래서FROM S3Object와FROM S3Object[*].path는 모두 유효한 절이지만,FROM S3Object.path는 유효하지 않아요.
예제
예제 #1 — 다음 데이터셋과 쿼리를 사용했을 때의 결과를 보여줘요.
{
"Rules": [
{
"id": "1"
},
{
"expr": "y > x"
},
{
"id": "2", "expr": "z = DEBUG"
}
]
}
{
"created": "June 27", "modified": "July 6"
}
SELECT id FROM S3Object[*].Rules[*].id
{
"id":"1"
}
{
}
{
"id":"2"
}
{
}
Amazon S3 Select는 각 결과를 다음 이유로 만들어요.
{ "id":"id-1" }–S3Object[0].Rules[0].id가 일치를 만들어냈어요.{ }–S3Object[0].Rules[1].id가 레코드와 일치하지 않아서 Amazon S3 Select가MISSING을 내보냈고, 출력 직렬화 중에 빈 레코드로 바뀌어 반환됐어요.{ "id":"id-2" }–S3Object[0].Rules[2].id가 일치를 만들어냈어요.{ }–S3Object[1]이Rules에서 일치하지 않아서 Amazon S3 Select가MISSING을 내보냈고, 출력 직렬화 중에 빈 레코드로 바뀌어 반환됐어요.
일치하는 항목이 없을 때 Amazon S3 Select가 빈 레코드를 반환하지 않게 하려면 MISSING 값을 검사할 수 있어요. 다음 쿼리는 이전 쿼리와 같은 결과를 반환하되, 빈 값을 제외해요.
SELECT id FROM S3Object[*].Rules[*].id WHERE id IS NOT MISSING
{
"id":"1"
}
{
"id":"2"
}
예제 #2 — 다음 데이터셋과 쿼리를 사용했을 때의 결과를 보여줘요.
{
"created": "936864000", "dir_name": "important_docs", "files": [
{
"name": "."
},
{
"name": ".."
},
{
"name": ".aws"
},
{
"name": "downloads"
}
], "owner": "Amazon S3"
}
{
"created": "936864000", "dir_name": "other_docs", "files": [
{
"name": "."
},
{
"name": ".."
},
{
"name": "my stuff"
},
{
"name": "backup"
}
], "owner": "User"
}
SELECT d.dir_name, d.files FROM S3Object[*] d
{
"dir_name":"important_docs","files":[
{
"name":"."
},
{
"name":".."
},
{
"name":".aws"
},
{
"name":"downloads"
}
]
}
{
"dir_name":"other_docs","files":[
{
"name":"."
},
{
"name":".."
},
{
"name":"my stuff"
},
{
"name":"backup"
}
]
}
SELECT _1.dir_name, _1.owner FROM S3Object[*]
{
"dir_name":"important_docs","owner":"Amazon S3"
}
{
"dir_name":"other_docs","owner":"User"
}
WHERE 절
WHERE 절은 다음 구문을 따라요.
WHERE condition
WHERE 절은 condition을 기준으로 행을 필터링해요. condition은 불리언 결과를 갖는 표현식이에요. 조건이 TRUE로 평가되는 행만 결과에 반환돼요.
LIMIT 절
LIMIT 절은 다음 구문을 따라요.
LIMIT number
LIMIT 절은 number를 기준으로 쿼리가 반환하려는 레코드 수를 제한해요.
속성 접근
SELECT 와 WHERE 절은, 조회되는 파일이 CSV인지 JSON 형식인지에 따라 다음 절의 방법 중 하나로 레코드 데이터를 참조할 수 있어요.
CSV
- 열 번호 –
_N이라는 열 이름으로 행의 N번째 열을 참조할 수 있어요. 여기서 N은 열 위치예요. 위치 수는 1부터 시작해요. 예를 들어 첫 번째 열은_1, 두 번째 열은_2로 이름을 붙여요. 열을_N또는alias._N으로 참조할 수 있어요. 예를 들어_2와myAlias._2는 둘 다 SELECT 목록과 WHERE 절에서 열을 참조하는 유효한 방법이에요. - 열 머리글 – 헤더 행이 있는 CSV 형식 객체의 경우, 머리글을 SELECT 목록과 WHERE 절에서 사용할 수 있어요. 특히 전통적인 SQL에서처럼 SELECT와 WHERE 절 표현식 안에서 열을
alias.column_name또는column_name으로 참조할 수 있어요.
JSON
- 문서 – JSON 문서 필드에
alias.name으로 접근할 수 있어요.alias.name1.name2.name3처럼 중첩된 필드에도 접근할 수 있어요. - 목록 –
[]연산자로 0부터 시작하는 인덱스를 사용해 JSON 목록의 요소에 접근할 수 있어요. 예를 들어 목록의 두 번째 요소는alias[1]로 접근할 수 있어요. 목록 요소 접근을 필드와 결합할 수도 있어요. 예를 들어alias.name1.name2[1].name3처럼요. - 예제 – 다음 JSON 객체를 샘플 데이터셋으로 생각해 볼게요.
{
"name": "Susan Smith",
"org": "engineering",
"projects":
[
{ "project_name":"project1", "completed":false},
{ "project_name":"project2", "completed":true}
]
}
예제 #1 — 다음 쿼리는 이런 결과를 반환해요.
Select s.name from S3Object s
{ "name":"Susan Smith"}
예제 #2 — 다음 쿼리는 이런 결과를 반환해요.
Select s.projects[0].project_name from S3Object s
{ "project_name":"project1"}
머리글과 속성 이름의 대소문자 구분
Amazon S3 Select에서는 큰따옴표를 사용해 열 머리글(CSV 객체용)과 속성(JSON 객체용)이 대소문자를 구분한다는 것을 나타낼 수 있어요. 큰따옴표가 없으면 객체 머리글과 속성은 대소문자를 구분하지 않아요. 모호한 경우에는 오류가 발생해요.
다음 예제들은 1) 지정된 열 머리글이 있고 요청에 대해 FileHeaderInfo를 "Use"로 설정한 CSV 형식의 Amazon S3 객체이거나, 2) 지정된 속성이 있는 JSON 형식의 Amazon S3 객체에 해당해요.
예제 #1 — 조회하는 객체에 NAME 머리글 또는 속성이 있어요.
- 다음 표현식은 객체에서 값을 성공적으로 반환해요. 따옴표가 없으므로 쿼리는 대소문자를 구분하지 않아요.
SELECT s.name from S3Object s - 다음 표현식은
MissingHeaderName400 오류를 발생시켜요. 따옴표가 있으므로 쿼리는 대소문자를 구분해요.SELECT s."name" from S3Object s
예제 #2 — 조회하는 Amazon S3 객체에 NAME 머리글 또는 속성과 name 머리글 또는 속성이 있어요.
- 다음 표현식은
AmbiguousFieldName400 오류를 발생시켜요. 따옴표가 없으므로 쿼리는 대소문자를 구분하지 않지만 일치하는 항목이 두 개라서 오류가 발생해요.SELECT s.name from S3Object s - 다음 표현식은 객체에서 값을 성공적으로 반환해요. 따옴표가 있으므로 쿼리는 대소문자를 구분해서 모호함이 없어요.
SELECT s."NAME" from S3Object s
예약 키워드를 사용자 정의 용어로 사용하기
Amazon S3 Select에는 객체 내용을 조회하는 데 쓰는 SQL 표현식을 실행하는 데 필요한 예약 키워드 집합이 있어요. 예약 키워드에는 함수 이름, 데이터 형식, 연산자 등이 포함돼요. 어떤 경우에는 열 머리글(CSV 파일)이나 속성(JSON 객체) 같은 사용자 정의 용어가 예약 키워드와 충돌할 수 있어요. 이때는 큰따옴표를 사용해서 예약 키워드와 충돌하는 사용자 정의 용어를 의도적으로 사용한다는 것을 나타내야 해요. 그렇지 않으면 400 파싱 오류가 발생해요.
예약 키워드 전체 목록은 Reserved keywords 문서를 참고하세요.
다음 예제는 1) 쿼리 요청에 대해 FileHeaderInfo가 "Use"로 설정된 지정된 열 머리글이 있는 CSV 형식의 Amazon S3 객체이거나, 2) 지정된 속성이 있는 JSON 형식의 Amazon S3 객체에 해당해요.
예제 — 조회하는 객체에 예약 키워드인 CAST라는 머리글 또는 속성이 있어요.
- 다음 표현식은 객체에서 값을 성공적으로 반환해요. 쿼리에 따옴표를 사용했으므로 S3 Select는 사용자 정의 머리글 또는 속성을 사용해요.
SELECT s."CAST" from S3Object s - 다음 표현식은 400 파싱 오류를 발생시켜요. 쿼리에 따옴표를 사용하지 않았으므로
CAST가 예약 키워드와 충돌해요.SELECT s.CAST from S3Object s
스칼라 표현식
WHERE 절과 SELECT 목록 안에는 스칼라 값을 반환하는 표현식인 SQL 스칼라 표현식을 둘 수 있어요. 그 형태는 다음과 같아요.
literal— SQL 리터럴.column_reference—column_name또는alias.column_name형태의 열 참조.unary_op expression— 여기서unary_op는 SQL 단항 연산자예요.expression binary_op expression— 여기서binary_op는 SQL 이항 연산자예요.func_name— 여기서func_name은 호출할 스칼라 함수의 이름이에요.expression [ NOT ] BETWEEN expression AND expressionexpression LIKE expression [ ESCAPE expression ]