13.2.9 SELECT 구문
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]] SELECT 는 하나 이상의 테이블에서 선택된 행을 검색하는 데 사용되며, UNION 문과 서브 쿼리를 포함 할 수 있습니다. 섹션 13.2.9.4 "UNION 구문" 및 섹션 13.2.10 "서브 쿼리 구문" 을 참조하십시오.
SELECT 문 가장 일반적으로 사용되는 어구는 다음과 같습니다.
각
select_expr는 검색 할 컬럼을 나타냅니다. 적어도 하나의select_expr이 존재해야합니다.table_references는 행을 검색하는 하나 이상의 테이블을 나타냅니다. 그 구문은 섹션 13.2.9.2 "JOIN" 에 설명되어 있습니다.MySQL 5.6.2에서
SELECT는table_reference의 테이블 이름 뒤에 파티션 또는 서브 파티션 (또는 둘 다)의 목록을 포함PARTITION키워드를 사용하여 명시 적 파티션 선택을 지원하고 있습니다 ( 섹션 13.2.9.2 "JOIN" 을 참조하십시오). 이 경우 행은 나열된 파티션에서만 선택된 테이블의 다른 파티션은 모두 무시됩니다. 자세한 내용 및 예제는 섹션 19.5 "파티션 선택" 을 참조하십시오.MySQL 5.6.6 이후에서는, 테이블 수준 잠금 (즉, 파티션 잠금)을 실행하는
MyISAM등의 스토리지 엔진을 사용하는 테이블에서SELECT ... PARTITION에서는PARTITION옵션에서 지정되는 파티션 또는 서브 파티션 만 고정됩니다.자세한 내용은 섹션 19.6.4 "파티셔닝 및 잠금" 을 참조하십시오.
WHERE절 (지정된 경우)은 선택되기 위하여 행이 충족해야하는 하나 이상의 조건을 나타냅니다.where_condition은 선택되는 각 행에 대해 true로 평가되는 식입니다.WHERE절이 없으면이 문은 모든 행을 선택합니다.WHERE식에서는 집계 (요약) 함수를 제외하고는 MySQL이 지원하는 모든 함수 및 연산자를 사용할 수 있습니다. 섹션 9.5 "식의 구문」 및 제 12 장 "함수 및 연산자" 를 참조하십시오.
SELECT 를 사용하여 어떤 테이블도 참조하지 않고 계산 된 행을 검색 할 수 있습니다.
예 :
mysql> SELECT 1 + 1;
-> 2
테이블이 참조되지 않는 상황에서는 더미 테이블 명으로서 DUAL 를 지정할 수 있도록되어 있습니다.
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL 은 순수하게 모든 SELECT 문에 FROM 이나, 경우에 따라서는 다른 어구가 있는지를 요구하는 사용자의 편의를 위해 제공되고 있습니다. MySQL은이 어구를 무시 될 수 있습니다. MySQL에서 테이블이 참조되지 않는 경우에도 FROM DUAL 은 필요 없습니다.
일반적으로 사용되는 어구는 정확하게 구문의 설명에 표시된 순서대로 지정해야합니다. 예를 들어, HAVING 절은 모든 GROUP BY 절 후에, 그리고 모든 ORDER BY 절 앞에 있어야합니다. 예외적으로 INTO 절은 구문의 설명에 표시된 위치하거나 select_expr 목록 직후에 모두 나타날 수 있습니다. INTO 대한 자세한 내용은 섹션 13.2.9.1 "SELECT ... INTO 구문" 을 참조하십시오.
select_expr 항 목록은 어느 컬럼을 취득 하는지를 나타내는 선택 목록으로 구성되어 있습니다. 이 절은 컬럼이나 표현식을 지정하거나 * 의 약어를 사용할 수 있습니다.
하나의 자격이되지 않는
*만 갖춰진 선택 목록은 모든 테이블의 모든 컬럼을 선택하는 단축형으로 사용할 수 있습니다.SELECT * FROM t1 INNER JOIN t2 ...는 지정된 테이블의 모든 열을 선택하기위한 자격이 된 약어로 사용할 수 있습니다.tbl_name.*SELECT t1 *, t2 * FROM t1 INNER JOIN t2 ...자격이되지 않은
*을 선택 목록에서 다른 항목과 함께 사용하면 구문 분석 오류가 생성 될 수 있습니다. 이 문제를 해결하려면 수정 된참조를 사용합니다.tbl_name.*SELECT AVG (score), t1 * FROM t1 ...
다음 목록은 기타 SELECT 절에 대한 추가 정보를 보여줍니다.
AS을 사용하여alias_nameselect_expr에 별칭을 지정할 수 있습니다. 별칭은 식의 컬럼 명으로 사용되며GROUP BY,ORDER BY또는HAVING절에서 사용할 수 있습니다. 예 :SELECT CONCAT (last_name ','first_name) AS full_name FROM mytable ORDER BY full_name;
select_expr별칭으로 식별자를 지정하는 경우,AS키워드는 옵션입니다. 앞의 예는 다음과 같이 설명 할 수있었습니다.SELECT CONCAT (last_name ','first_name) full_name FROM mytable ORDER BY full_name;
그러나
AS는 옵션이기 때문에 두select_expr식 콤마를 잊는다면 사소한 문제가 발생할 수 있습니다. MySQL은 두 번째 식을 별칭으로 해석합니다. 예를 들어, 다음 명령문은columnb는 별칭으로 처리됩니다.SELECT columna columnb FROM mytable;따라서 열 별칭을 지정할 때는
AS를 명시 적으로 사용하도록하는 것이 좋습니다.WHERE절이 실행될 때 아직 컬럼 값이 결정되지 않을 수 있기 때문에WHERE절에 컬럼 별칭을 참조하는 것은 허용되지 않습니다. 섹션 B.5.5.4 "컬럼 별칭 문제" 를 참조하십시오.FROM절은 행을 검색하는 하나 이상의 테이블을 나타냅니다. 여러 테이블을 지정하면 결합이 실행됩니다. 결합 구문에 대해서는 섹션 13.2.9.2 "JOIN" 을 참조하십시오. 지정된 테이블에 대해 선택적으로 별칭을 지정할 수 있습니다.table_referencestbl_name[AS]alias] [index_hint]인덱스 힌트를 사용하면 쿼리 처리 중에 인덱스를 선택하는 방법에 대한 정보가 최적화에 제공됩니다. 이러한 힌트를 지정하는 구문은 섹션 13.2.9.3 "인덱스 힌트 구문" 을 참조하십시오.
대안으로
SET max_seeks_for_key=를 사용하여 MySQL에 테이블 스캔 대신 키 스캔을 강제로 실행시킬 수 있습니다. 섹션 5.1 "서버 시스템 변수" 를 참조하십시오.value데이터베이스를 명시 적으로 지정하기 위해 기본 데이터베이스에서 테이블을
tbl_name또는db_name.tbl_name로 볼 수 있습니다. 열을col_name,tbl_name.col_name또는db_name.tbl_name.col_name로 볼 수 있습니다. 참조가 모호하지 않는 한 컬럼 참조에 대한tbl_name또는db_name.tbl_name접두어를 지정할 필요가 없습니다. 보다 명시적인 컬럼 참조 형식을 필요로하는 모호함의 예는 섹션 9.2.1 "식별자의 규정" 을 참조하십시오.또는tbl_nameASalias_nametbl_name alias_name을 사용하여 테이블 참조에 별칭을 지정할 수 있습니다.SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
컬럼 명, 컬럼 별칭 또는 컬럼 위치를 사용하여 출력을 위해 선택된 컬럼을
ORDER BY와GROUP BY절에서 볼 수 있습니다. 열 위치는 정수이며 1부터 시작합니다.SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;
역순으로 정렬하려면 정렬에 사용하는
ORDER BY절의 컬럼의 이름에DESC(내림차순) 키워드를 추가합니다. 기본값은 오름차순입니다. 이것은ASC키워드를 사용하여 명시 적으로 지정할 수 있습니다.ORDER BY가 서브 쿼리에서 발생하는 외부 쿼리에 적용되는 경우 가장 외부에있는ORDER BY가 우선됩니다. 예를 들어, 다음 명령문의 결과는 오름차순이 아닌 내림차순으로 정렬됩니다.(SELECT ... ORDER BY a) ORDER BY a DESC;컬럼 위치의 사용이 구문이 SQL 표준에서 삭제 되었기 때문에 비추천입니다.
GROUP BY를 사용하면 출력 행은 동일한 컬럼에ORDER BY를 지정한 것처럼GROUP BY컬럼에 따라 정렬됩니다.GROUP BY에 의해 생성되는 정렬의 오버 헤드를 방지하려면ORDER BY NULL을 추가합니다.SELECT a, COUNT (b) FROM test_table GROUP BY a ORDER BY NULL;MySQL 5.6에서 암시 적
GROUP BY정렬에 의존는 비추천되어 있습니다. 그룹화 된 결과 특정 정렬 순서를 실현하려면 명시 적ORDER BY절을 사용하는 것이 좋습니다.GROUP BY정렬 예를 들어, 최적화가 가장 효율적이라고 생각 어떠한 방법으로도 그룹화를 지시 할 수있게하거나 정렬 오버 헤드를 방지하는 데 등에 향후 릴리스에서 변경 될 수 성있는 MySQL 확장 기능입니다.MySQL은
GROUP BY절을 확장하여이 절에 지정되어있는 컬럼의 뒤에ASC와DESC를 지정할 수 있도록되어 있습니다.SELECT a, COUNT (b) FROM test_table GROUP BY a DESC;MySQL 그럼,
GROUP BY의 사용이GROUP BY절에 지정되어 있지 않은 필드의 선택을 허용하도록 확장되어 있습니다. 쿼리에서 원하는 결과를 얻지 못할 경우, 섹션 12.19 "GROUP BY 절에서 사용되는 함수와 수식" 에있는GROUP BY의 설명을 참조하십시오.GROUP BY는WITH ROLLUP수식이 허용됩니다. 섹션 12.19.2 "GROUP BY 수식" 을 참조하십시오.HAVING절은 거의 마지막 (항목이 클라이언트로 전송되기 직전)에 최적화없이 적용됩니다. (LIMIT는HAVING다음에 적용됩니다.)SQL 표준은
HAVING은GROUP BY절의 컬럼 또는 집계 함수에서 사용되는 컬럼 밖에 볼 수 없습니다. 그러나 MySQL에서는이 동작에 대한 확장을 지원하고 있으며,HAVING이SELECT목록의 열이나 외부 하위 쿼리의 컬럼을 참조하는 것도 허용됩니다.HAVING절이 모호한 컬럼을 참조하는 경우 경고가 발생합니다. 다음 설명의col2는 컬럼 이름과 alias 모두로 사용되고 있기 때문에 모호합니다.SELECT COUNT (col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;표준 SQL 작업 방식이 우선되기 때문에
HAVING컬럼 이름이GROUP BY에 사용되는 동시에 출력 컬럼 목록에서 별칭이 지정된 컬럼으로도 사용되는 경우,GROUP BY컬럼에서 컬럼이 우선됩니다.WHERE절에 포함 할 항목은HAVING을 사용하지 마십시오. 예를 들어, 다음과 같이 기술하지 마십시오.SELECTcol_nameFROMtbl_nameHAVINGcol_name> 0;대신 다음과 같이 설명합니다.
SELECTcol_nameFROMtbl_nameWHEREcol_name> 0;HAVING절은WHERE절을 참조 할 수없는 집계 함수를 참조 할 수 있습니다.SELECT user, MAX (salary) FROM users GROUP BY user HAVING MAX (salary)> 10;
(이것은 일부 이전 버전의 MySQL에서는 작동하지 않았습니다.)
MySQL에서 중복 된 컬럼 이름이 허용됩니다. 즉, 동일한 이름을 가진 여러
select_expr가있을 수 있습니다. 이것은 표준 SQL의 확장입니다. MySQL은GROUP BY와HAVING이select_expr값을 참조 할 수 있도록하기 때문에 이로 인해 모호성이 발생할 수 있습니다.SELECT 12 AS a, a FROM t GROUP BY a;이 문은 두 컬럼의 이름도
a입니다. 그룹화에 대한 올바른 컬럼이 사용되도록하기 위해select_expr마다 다른 이름을 사용하십시오.MySQL은
ORDER BY절에 규정되지 않은 컬럼 또는 별칭 참조를 먼저select_expr값 다음FROM절에서 테이블의 컬럼에서 검색하여 해결합니다.GROUP BY또는HAVING절의 경우select_expr치내를 검색하기 전에FROM절을 검색합니다. (GROUP BY와HAVING대해 이것은ORDER BY)의 경우와 동일한 규칙을 사용했다 MySQL 5.0 이전의 동작과는 다릅니다.LIMIT절을 사용하면SELECT문에서 반환되는 행 수를 제한 할 수 있습니다.LIMIT는 하나 또는 두 개의 숫자 인수를받습니다. 이것은 모두 음수가 아닌 정수 상수이어야합니다. 그러나 다음과 같은 예외가 있습니다.준비된 문은
?플레이스 홀더 마커를 사용하여LIMIT매개 변수를 지정할 수 있습니다.저장 프로그램에서 정수 값의 루틴 파라미터 또는 로컬 변수를 사용하여
LIMIT매개 변수를 지정할 수 있습니다.
인수가 2 개의 경우 첫 번째 인수는 반환 선두 행의 오프셋을 지정하고 두 번째 인수는 반환 최대 행 수를 지정합니다. 첫 번째 행의 오프셋 (1 대신) 0입니다.
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15특정 오프셋에서 결과 세트의 마지막까지의 모든 행을 검색하기 위해 두 번째 매개 변수에 어느 정도 큰 숫자를 사용할 수 있습니다. 다음 문은 96 번째 줄부터 마지막 줄까지의 모든 행을 가져옵니다.
SELECT * FROM tbl LIMIT 95,18446744073709551615;인수가 하나 인 경우이 값은 결과 집합의 처음부터 반환 할 행 수를 지정합니다.
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows즉,
LIMIT는row_countLIMIT 0,과 동일합니다.row_count준비된 문은 자리 표시자를 사용할 수 있습니다. 다음 문은
tbl테이블의 행을 반환합니다.SET @ a = 1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT?'; EXECUTE STMT USING @a;
다음 문은
tbl테이블의 두 번째 행에서 6 행까지를 반환합니다.SET @ skip = 1; SET @ numrows = 5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT?,?'; EXECUTE STMT USING @skip, @numrows;
PostgreSQL과의 호환성을 위해, MySQL은
LIMIT구문도 지원하고 있습니다.row_countOFFSEToffsetLIMIT가 하위 쿼리에 나타나 또 외부 쿼리에 적용되는 경우 가장 바깥 쪽의LIMIT가 우선됩니다. 예를 들어, 다음 문은 한 줄이 아니라 두 줄을 생성합니다.(SELECT ... LIMIT 1) LIMIT 2;PROCEDURE절은 결과 집합의 데이터를 처리하는 프로 시저를 지정합니다. 예를 들어, 섹션 8.4.2.4 "PROCEDURE ANALYSE 사용" 을 참조하십시오. 여기에서는 테이블 크기 감소에 도움이 될 수있는 최적의 컬럼 데이터 유형에 관한 제안을 얻는 데 사용할 수있는 프로 시저 인ANALYSE에 대해 설명하고 있습니다.SELECT의SELECT ... INTO형식을 사용하면 쿼리 결과를 파일에 쓰거나 변수에 저장 할 수 있습니다. 자세한 내용은 섹션 13.2.9.1 "SELECT ... INTO 구문" 을 참조하십시오.페이지 또는 행 잠금을 사용하는 스토리지 엔진에서
FOR UPDATE를 사용하면 쿼리에 의해 검사되는 행은 현재 트랜잭션이 끝날 때까지 쓰기 잠금이 설정됩니다.LOCK IN SHARE MODE를 사용하면 검사되는 행의 다른 트랜잭션에서 읽을 수는 있지만, 갱신 또는 삭제를 허용하지 않는 공유 잠금이 설정됩니다. 섹션 14.2.5 "잠금 읽기 (SELECT ... FOR UPDATE 및 SELECT ... LOCK IN SHARE MODE)" 를 참조하십시오.또한
CREATE TABLE등의 문에서new_tableSELECT ... FROMold_table...SELECT의 일부로FOR UPDATE를 사용할 수 없습니다. (그것을하려고하면이 문은 오류 Can not update table 'old_table'while'new_table'is being created 거부됩니다.) 이것은CREATE TABLE ... SELECT문이 작성되는 테이블 이외의 테이블에서 변경할 수 있도록했다, MySQL 5.5 및 그 이전부터 동작의 변경입니다.
SELECT 키워드 다음에이 명령문 조작에 영향을 미치는 몇 가지 옵션을 사용할 수 있습니다. HIGH_PRIORITY , STRAIGHT_JOIN 및 SQL_ 로 시작되는 옵션은 표준 SQL에 대한 MySQL 확장입니다.
ALL및DISTINCT옵션은 중복 행을 반환할지 여부를 지정합니다.ALL(기본값)은 중복을 포함하여 일치하는 모든 행을 반환하도록 지정합니다.DISTINCT는 중복 된 행의 결과 세트에서 삭제를 지정합니다. 두 옵션을 지정하면 오류가 발생합니다.DISTINCTROW는DISTINCT의 동의어입니다.HIGH_PRIORITY는SELECT테이블을 갱신하는 스테이트먼트보다 높은 우선 순위를 부여합니다. 이것은 매우 빠른이자 즉시 실행해야하는 쿼리에만 사용하도록하십시오. 테이블이 읽기에 잠겨있는 사이에 발행 된SELECT HIGH_PRIORITY쿼리는 테이블이 미사용되는 것을 기다리는 업데이트 문이있는 경우에도 실행됩니다. 이것은 테이블 수준 잠금만을 사용하는 스토리지 엔진 (MyISAM,MEMORY및MERGE)에만 영향을 미칩니다.HIGH_PRIORITY를UNION의 일부인SELECT문에서 사용할 수 없습니다.STRAIGHT_JOIN은 최적화 테이블을FROM절에 나열된 순서대로 강제로 결합시킵니다. 최적화가 테이블을 최적화되지 않은 순서로 결합하는 경우이를 사용하여 쿼리 속도를 높일 수 있습니다.STRAIGHT_JOIN또한table_references목록에서도 사용할 수 있습니다. 섹션 13.2.9.2 "JOIN" 을 참조하십시오.STRAIGHT_JOIN은 최적화가const테이블 또는system테이블로 처리하는 테이블에는 적용되지 않습니다. 이러한 테이블은 단일 행을 생성하고 쿼리 실행의 최적화 단계에서 읽습니다. 또한, 그 컬럼에 대한 참조는 쿼리 실행이 계속되기 전에 적절한 컬럼 값으로 대체됩니다. 이 테이블은EXPLAIN에 의해 표시되는 쿼리 계획에 먼저 표시됩니다. ' 섹션 8.8.1 "EXPLAIN으로 쿼리 최적화" "를 참조하십시오. 이 예외는 외부 조인NULL로 보완 된 측면에 사용되는const테이블 또는system테이블 (즉,LEFT JOIN의 오른쪽 테이블 또는RIGHT JOIN왼쪽 테이블)에 적용되지 않을 수 있습니다.SQL_BIG_RESULT또는SQL_SMALL_RESULT는 결과 집합의 행 수가 각각 많기 또는 적은 수를 최적화에 통지하기 위해서GROUP BY또는DISTINCT와 함께 사용할 수 있습니다.SQL_BIG_RESULT의 경우 MySQL은 필요에 따라 디스크 기반의 임시 테이블을 직접 사용하여 정렬에서는GROUP BY요소에 대한 키에서 임시 테이블을 사용하는 것을 선호합니다.SQL_SMALL_RESULT의 경우 MySQL은 정렬을 사용하는 대신 빠른 임시 테이블을 사용하여 결과 테이블을 저장합니다. 이것은 일반적으로 필요없는 것입니다.SQL_BUFFER_RESULT는 결과를 강제로 임시 테이블에 배치합니다. 이것은 MySQL이 테이블 잠금을 조기에 확보하거나 결과 세트를 클라이언트에 전송하는 데 오랜 시간이 걸릴 수 있습니다. 이 옵션은 하위 쿼리 또는 후속UNION대신 최상위SELECT문에서만 사용할 수 있습니다.SQL_CALC_FOUND_ROWS은 MySQL에LIMIT절을 무시하고 결과 세트에 포함되는 행 수를 계산하도록 지시합니다. 그 후, 행수는SELECT FOUND_ROWS()를 사용하여 얻을 수 있습니다. 섹션 12.14 "정보 함수" 를 참조하십시오.SQL_CACHE및SQL_NO_CACHE옵션은 쿼리 캐시에서 쿼리 결과 캐시에 영향을줍니다 ( 섹션 8.9.3 "MySQL 쿼리 캐시" 를 참조하십시오).SQL_CACHE는 MySQL에 결과가 캐시 가능하며,query_cache_type시스템 변수의 값이2또는DEMAND인 경우 결과를 쿼리 캐시에 저장하도록 지시합니다.SQL_NO_CACHE를 지정하면 서버는 쿼리 캐시를 사용하지 않습니다. 그것은 결과가 이미 캐시되어 있는지 여부를 확인하기 위해 쿼리 캐시를 검사하지 않고 쿼리 결과를 캐시하지 않습니다. (파서의 제한으로 인해 공백 문자의 전후에SQL_NO_CACHE키워드를 지정해야합니다. 줄 바꿈 등의 공간 이외에서는 결과가 이미 캐시되어 있는지 여부를 확인하기 위해 서버에 쿼리 캐시를 검사합니다. )뷰의 경우
SQL_NO_CACHE는 쿼리에서 하나의SELECT나타난 경우에 적용됩니다. 캐시 가능한 쿼리는SQL_CACHE는 그 쿼리에 의해 참조되는 뷰의 첫 번째SELECT나타난 경우에 적용됩니다.MySQL 5.6에서는 이러한 두 가지 옵션은 상호 배타적이며, 모두가 지정된 경우 오류가 발생합니다. 또한이 옵션은 서브 쿼리 (
FROM절의 서브 쿼리를 포함)와 첫 번째SELECT를 제외 합집합의SELECT문에서 허용되지 않습니다.
MySQL 5.6.6 이전에는 테이블 수준의 잠금을 채용 한 MyISAM 등의 스토리지 엔진을 사용하여 파티션 된 테이블에서 SELECT 에 의해 그 테이블의 모든 파티션이 잠겨있었습니다. 이것은 SELECT ... PARTITION 쿼리에 적용했습니다. (이것은 행 레벨 락을 채용 한 InnoDB 등의 스토리지 엔진에서 발생하지 않았고 현재도 발생하지 않습니다.) MySQL 5.6.6 이후에서는, MySQL은 파티션 잠금 가지 치기를 사용합니다. 이렇게하면 SELECT 문 WHERE 절에 일치하는 행을 포함하는 파티션 만 실제로 잠기도록합니다. 자세한 내용은 섹션 19.6.4 "파티셔닝 및 잠금" 을 참조하십시오.