13.2.10.8 Выведенные таблицы
Выведенная таблица — это выражение, которое генерирует таблицу в рамках области запроса FROM. Например, подзапрос в операторе SELECT операторе FROM является выведенной таблицей:
SELECT ... FROM (subquery) [AS] tbl_name ...
Оператор [AS] является обязательным, потому что каждая таблица в операторе tbl_nameFROM должна иметь имя. Все столбцы в выведенной таблице должны иметь уникальные имена.
Для наглядности предположим, что у вас есть такая таблица:
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;
Результат:
+------+------+------+
| sb1 | sb2 | sb3 |
+------+------+------+
| 2 | 2 | 4 |
+------+------+------+
Вот еще один пример: Предположим, что вы хотите узнать среднее значение набора сумм для сгруппированной таблицы. Это не сработает:
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), распознается в внешнем запросе.
Выведенная таблица может возвращать скаляр, столбец, строку или таблицу.
Выведенные таблицы ограничены следующими условиями:
Выведенная таблица не может быть коррелированным подзапросом.
Выведенная таблица не может содержать ссылки на другие таблицы того же оператора
SELECT.Выведенная таблица не может содержать внешние ссылки. Это ограничение MySQL, а не ограничение стандарта SQL.
Оптимизатор определяет информацию о выведенных таблицах таким образом, что EXPLAIN не нужно их материализовывать. См. Раздел 8.2.2.4, «Оптимизация выведенных таблиц и ссылок на представления с помощью слияния или материализации».
В определенных обстоятельствах использование EXPLAIN
SELECT может изменить данные таблицы. Это может произойти, если внешний запрос обращается к каким-либо таблицам, а внутренний запрос вызывает хранимую функцию, которая изменяет одну или несколько строк таблицы. Предположим, что в базе данных d1 существуют две таблицы t1 и t2, и хранимая функция f1, которая изменяет t2, создана следующим образом:
CREATE DATABASE d1;
USE d1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE FUNCTION f1(p1 INT) RETURNS INT
BEGIN
INSERT INTO t2 VALUES (p1);
RETURN p1;
END;
Прямое обращение к функции в EXPLAIN
SELECT не влияет на t2, как показано ниже:
mysql> SELECT * FROM t2;
Empty set (0.02 sec)
mysql> EXPLAIN SELECT f1(5)\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
partitions: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
filtered: NULL
Extra: No tables used
1 row in set (0.01 sec)
mysql> SELECT * FROM t2;
Empty set (0.01 sec)
Это происходит потому, что оператор SELECT не ссылался на какие-либо таблицы, как видно в столбцах table и Extra вывода. Это также верно для следующих вложенных операторов SELECT:
mysql> EXPLAIN SELECT NOW() AS a1, (SELECT f1(5)) AS a2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
filtered: NULL
Extra: 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)
Однако, если внешний оператор SELECT ссылается на какие-либо таблицы, оптимизатор выполняет оператор в подзапросе также, в результате чего t2 изменяется:
mysql> EXPLAIN SELECT * FROM t1 AS a1, (SELECT f1(5)) AS a2\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: <derived2>
partitions: NULL
type: system
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: PRIMARY
table: a1
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1
filtered: 100.00
Extra: NULL
*************************** 3. row ***************************
id: 2
select_type: DERIVED
table: NULL
partitions: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
filtered: NULL
Extra: No tables used
3 rows in set (0.00 sec)
mysql> SELECT * FROM t2;
+------+
| c1 |
+------+
| 5 |
+------+
1 row in set (0.00 sec)
© 2025 Oracle
Licensed under the GPLv2 License.