• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.6 한글메뉴얼) [close]
  • 1. MySQL 5.6 새로운 기능
  • 2. MySQL 설치 및 업그레이드
  • 3. MySQL Tutorial
  • 4. MySQL 프로그램
  • 5. MySQL 서버관리
  • 6. 보안
  • 7. 백업 및 복구
  • 8. 최적화
  • 9. Language Structure(언어구조)
  • 10. Character Sets(Globalization)
  • 11. 데이터형(Data Types)
  • 12. 함수와 연산자
  • 13. SQL 문법
  • 1. 데이터 정의 문
    2. 데이터 조작 문
    1. CALL 구문
    2. DELETE 구문
    3. DO 구문
    4. HANDLER 구문
    5. INSERT 구문
    6. LOAD DATA INFILE 구문
    7. LOAD XML 구문
    8. REPLACE 구문
    9. SELECT 구문
    10. 서브 쿼리 구문
    1. 스칼라 피연산자로 서브 쿼리
    2. 서브 쿼리를 사용한 비교
    3. ANY, IN 또는 SOME을 사용한 서브 쿼리
    4. ALL을 사용한 서브 쿼리
    5. 13.2.10.5 row(행) 서브 쿼리
    6. EXISTS 또는 NOT EXISTS를 사용한 서브 쿼리
    7. 상관 서브 쿼리
    8. FROM절의 서브 쿼리
    9. 서브 쿼리 오류
    10. 서브 쿼리의 최적화
    11. 서브 쿼리의 결합으로 재 작성
    11. UPDATE 구문
    3. MySQL 트랜잭션과 잠금 문
    4. 복제 문
    5. Prepared Statements위한 SQL 구문
    6. MySQL 복합문 구문
    7. 데이터베이스 관리 문
    8. MySQL 유틸리티 문
  • 14. InnoDB 스토리지 엔진
  • 15. 기타 스토리지 엔진
  • 16. 고가용성 및 확장성
  • 17. 리플리케이션
  • 18. MySQL Cluster
  • 19. 파티셔닝
  • 20. Stored Programs and Views
  • 21. INFORMATION_SCHEMA
  • 22. PERFORMANCE SCHEMA
  • 23. 컨넥터 및 API
  • 24. MySQL 확장
  • 25. MySQL Enterprise Edition
  • 26. MySQL Workbench
  • 27. 제약 및 제한
  • 28. MySQL 5.7 새로운 기능

13.2.10.8 FROM 절의 서브 쿼리

서브 쿼리는 SELECT 문의 FROM 절에서 합법적입니다. 그 실제 구문은 다음과 같습니다.

 SELECT ... FROM ( subquery ) [AS] name ...

FROM 절에 어떤 테이블도 이름을 가지고있을 필요가 있기 때문에 [AS] name 절은 필수입니다. subquery 선택 목록에 열이 있으면 그것이 고유 한 이름을 가지고 있어야합니다.

설명을 위해 다음과 같은 테이블이 있다고합니다.

 CREATE TABLE t1 (s1 INT, s2 CHAR (5), s3 FLOAT);

이 테이블의 예를 사용하여 FROM 절에 서브 쿼리를 사용하는 방법을 보여줍니다.

 INSERT INTO t1 VALUES (1, '1', 1.0);
 INSERT INTO t1 VALUES (2, '2', 2.0);
 SELECT sb1, sb2, sb3
   FROM (SELECT s1 AS sb1, s2 AS sb2, s3 * 2 AS sb3 FROM t1) AS sb
   WHERE sb1> 1;

결과 : 2, '2', 4.0 .

다음 다른 예입니다. 그룹화 된 테이블에 대한 일련의 합계의 평균을 알고 자합니다. 다음 쿼리는 작동하지 않습니다.

 SELECT AVG (SUM (column1)) FROM t1 GROUP BY column1;

다만, 다음의 쿼리는 원하는 정보를 제공합니다.

 SELECT AVG (sum_column1)
   FROM (SELECT SUM (column1) AS sum_column1
         FROM t1 GROUP BY column1) AS t1;

서브 쿼리에서 사용되는 컬럼 이름 ( sum_column1 )는 외부 쿼리에서 인식됩니다.

FROM 절의 서브 쿼리는 스칼라, 열, 행 또는 테이블을 반환 할 수 있습니다. FROM 절의 서브 쿼리는 JOIN 작업의 ON 절에서 사용되지 않는 한 상관 서브 쿼리 할 수 없습니다.

MySQL 5.6.3 이전에는 FROM 절의 서브 쿼리는 EXPLAIN 문에 대해서도 실행됩니다 (즉, 파생 된 임시 테이블이 구체화됩니다). 이것은 최적화 단계에서 상위 수준의 쿼리 모든 테이블에 대한 정보가 필요하며 서브 쿼리가 실행되지 않는 한 FROM 절의 서브 쿼리에 의해 표현되는 테이블을 사용할 수 없기 때문에 발생합니다. MySQL 5.6.3의 시점에서는 최적화 파생 테이블에 대한 정보를 다른 방법으로 특정하기 위해 그 실체화가 EXPLAIN 에 대해 발생하지 않습니다. 섹션 8.2.1.18.3 "FROM 절의 서브 쿼리 (파생 테이블)의 최적화" 를 참조하십시오.

특정 상황에서는 EXPLAIN SELECT 를 사용하여 테이블 데이터를 변경할 수 있습니다. 이것은 외부 쿼리가 하나의 테이블에 액세스하고 내부 쿼리가 테이블의 하나 이상의 행을 변경하는 스토어드 함수를 호출하는 경우에 발생할 수 있습니다. 데이터베이스 d1 에 다음과 같이 생성 된 2 개의 테이블 t1 과 t2 가 있다고합니다.

 mysql> CREATE DATABASE d1;
 Query OK, 1 row affected (0.00 sec)

 mysql> USE d1;
 Database changed

 mysql> CREATE TABLE t1 (c1 INT);
 Query OK, 0 rows affected (0.15 sec)

 mysql> CREATE TABLE t2 (c1 INT);
 Query OK, 0 rows affected (0.08 sec)

여기서 t2 를 변경하는 스토어드 함수 f1 을 만듭니다.

 mysql> DELIMITER //
 mysql> CREATE FUNCTION f1(p1 INT) RETURNS INT
 mysql> BEGIN
 mysql> INSERT INTO t2 VALUES (p1);
 mysql> RETURN p1;
 mysql> END //
 Query OK, 0 rows affected (0.01 sec)

 mysql> DELIMITER ;

다음과 같이 EXPLAIN SELECT 에서이 함수를 직접 참조해도 t2 에는 아무런 영향을주지 않습니다.

 mysql> SELECT * FROM t2;
 Empty set (0.00 sec)

mysql> SELECT * FROM t2;
Empty set (0.00 sec)

mysql> EXPLAIN SELECT f1(5);
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | No tables used |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t2;
Empty set (0.00 sec)

이것은 출력 table 및 Extra 컬럼에서 알 수 있듯이, SELECT 문이 어떤 테이블도 참조 않았기 때문입니다. 이것은 또한 다음 중첩 된 SELECT 에도 적용됩니다.

mysql> EXPLAIN SELECT NOW() AS a1, (SELECT f1(5)) AS a2;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | PRIMARY     | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | No tables used |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Note  | 1249 | Select 2 was reduced during optimization |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM t2;
Empty set (0.00 sec)

 mysql> SELECT * FROM t2;
 Empty set (0.00 sec)

그러나 외부 SELECT 가 하나의 테이블을 참조하는 경우 최적화 프로그램은 하위 쿼리 문을 실행합니다.

mysql> EXPLAIN SELECT * FROM t1 AS a1, (SELECT f1(5)) AS a2;
+----+-------------+------------+--------+---------------+------+---------+------+------+---------------------+
| id | select_type | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra               |
+----+-------------+------------+--------+---------------+------+---------+------+------+---------------------+
|  1 | PRIMARY     | a1         | system | NULL          | NULL | NULL    | NULL |    0 | const row not found |
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL | NULL    | NULL |    1 |                     |
|  2 | DERIVED     | NULL       | NULL   | NULL          | NULL | NULL    | NULL | NULL | No tables used      |
+----+-------------+------------+--------+---------------+------+---------+------+------+---------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM t2;
+------+
| c1   |
+------+
|    5 |
+------+
1 row in set (0.00 sec)

이것은 또한 다음과 같은 EXPLAIN SELECT 문은 t1 의 행마다 1 회 BENCHMARK() 함수가 실행되기 때문에 실행 시간이 오래 걸릴 수 있다는 것도 보여줍니다.

 EXPLAIN SELECT * FROM t1 AS a1, (SELECT BENCHMARK (1000000 MD5 (NOW ())));


서울시 강남구 영동대로 602 6층
TEL: 02-6061-0006  /  E: csr@mysqlkorea.com
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved