mysql - una - seleccionar el registro con el mayor valor en un campo sql
Orden de ejecución de consulta/cláusula MySQL (3)
¿Cuál es el orden predefinido en el cual las cláusulas se ejecutan en MySQL? ¿Se decide algo en tiempo de ejecución y es correcto este orden?
FROM clause
-
WHERE clause
-
GROUP BY clause
-
HAVING clause
-
SELECT clause
-
ORDER BY clause
Creo que el orden de ejecución es así:
(7) SELECT
(8) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>[, <offset_number>]
La ejecución real de las declaraciones de MySQL es un poco complicado. Sin embargo, el estándar sí especifica el orden de interpretación de los elementos en la consulta. Esto es básicamente en el orden que especifique, aunque creo que HAVING
y GROUP BY
podrían venir después de SELECT
:
- Cláusula
FROM
- Cláusula
WHERE
- Cláusula
SELECT
- Cláusula
GROUP BY
-
HAVING
cláusula - Cláusula
ORDER BY
Esto es importante para entender cómo se analizan las consultas. No puede usar un alias de columna definido en un SELECT
en la cláusula WHERE
, por ejemplo, porque WHERE
se analiza antes de SELECT
. Por otro lado, dicho alias puede estar en la cláusula ORDER BY
.
En cuanto a la ejecución real, eso realmente queda en manos del optimizador. Por ejemplo:
. . .
GROUP BY a, b, c
ORDER BY NULL
y
. . .
GROUP BY a, b, c
ORDER BY a, b, c
ambos tienen el efecto de que ORDER BY
no se ejecuta en absoluto, y por lo tanto no se ejecuta después de GROUP BY
(en el primer caso, el efecto es eliminar la clasificación de GROUP BY
y en el segundo el efecto es no hacer nada más que el GROUP BY
ya lo hace).
Así es como puedes obtener la idea aproximada de cómo mysql ejecuta la consulta de selección
DROP TABLE if exists new_table;
CREATE TABLE `new_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`testdecimal` decimal(6,2) DEFAULT NULL,
PRIMARY KEY (`id`));
INSERT INTO `new_table` (`testdecimal`) VALUES (''1234.45'');
INSERT INTO `new_table` (`testdecimal`) VALUES (''1234.45'');
set @mysqlorder := '''';
select @mysqlorder := CONCAT(@mysqlorder," SELECT ") from new_table,(select @mysqlorder := CONCAT(@mysqlorder," FROM ")) tt
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN1 ")) t on ((select @mysqlorder := CONCAT(@mysqlorder," ON1 ")) or rand() < 1)
JOIN (select @mysqlorder := CONCAT(@mysqlorder," JOIN2 ")) t2 on ((select @mysqlorder := CONCAT(@mysqlorder," ON2 ")) or rand() < 1)
where ((select @mysqlorder := CONCAT(@mysqlorder," WHERE ")) or IF(new_table.testdecimal = 1234.45,true,false))
group by (select @mysqlorder := CONCAT(@mysqlorder," GROUPBY ")),id
having (select @mysqlorder := CONCAT(@mysqlorder," HAVING "))
order by (select @mysqlorder := CONCAT(@mysqlorder," ORDERBY "));
select @mysqlorder;
Y aquí está la salida de la consulta mysql anterior, espero que puedas averiguar la ejecución de mysql de una consulta SELECT : -
DESDE JOIN1 JOIN2 DONDE ON2 ON1 ORDERBY GROUPBY SELECCIONE DONDE ON2 ON1 ORDERBY GROUPBY SELECCIONE TENER TIEMPO