Está en la página 1de 6

Subconsulta

Una subconsulta (subquery) es una sentencia "select" anidada en


otra sentencia "select", "insert", "update" o "delete" (o en otra
subconsulta).

Las subconsultas se emplean cuando una consulta es muy compleja,


entonces se la divide en varios pasos lógicos y se obtiene el
resultado con una única instrucción y cuando la consulta depende
de los resultados de otra consulta.

Generalmente, una subconsulta se puede reemplazar por


combinaciones.

Las subconsultas se DEBEN incluir entre paréntesis.

Puede haber subconsultas dentro de subconsultas.

Se pueden emplear subconsultas:

- En lugar de una expresión, siempre que devuelvan un solo valor


o una lista de valores.

- Que retornen un conjunto de registros de varios campos en


lugar de una tabla o para obtener el mismo resultado que una
combinación (join).

Hay tres tipos básicos de subconsultas:

las que retornan un solo valor escalar que se utiliza con un


operador de comparación o en lugar de una expresión.
las que retornan una lista de valores, se combinan con "in", o
los operadores "any", "some" y "all".
los que testean la existencia con "exists".
Reglas a tener en cuenta al emplear subconsultas:

- La lista de selección de una subconsulta que va luego de un


operador de comparación puede incluir sólo una expresión o campo
(excepto si se emplea "exists" y "in").

- Li el "where" de la consulta exterior incluye un campo, este


debe ser compatible con el campo en la lista de selección de la
subconsulta.

- Las subconsultas luego de un operador de comparación (que no


es seguido por "any" o "all") no pueden incluir cláusulas "group
by" ni "having".

- "distinct" no puede usarse con subconsultas que incluyan


"group by".

- Una subconsulta puede estar anidada dentro del "where" o "having"


de una consulta externa o dentro de otra subconsulta.

- Si una tabla se nombra solamente en una subconsulta y no en la


consulta externa, los campos no serán incluidos en la salida (en
la lista de selección de la consulta externa).
Vista
Una vista es una tabla virtual que se genera a partir de una
consulta de selección. Dicho de otro modo. Escribimos una consulta
de selección (sobre una o más tablas) para leer los datos, y
almacenamos el resultado en una vista. Si usas PHPMyAdmin, la
vista te aparecerá como un elemento más de la base de datos en
curso. Al pulsar sobre ella, verás el resultado de la consulta de
selección, como si fuera una tabla más, aunque con ciertas
limitaciones (no puedes editar o añadir registros, por ejemplo)
porque lo que estás viendo no es una tabla, sino el resultado de
una consulta.
La ventaja que tienes es que si actualizas las tablas originales
(en el proceso en curso, o desde cualquier otro punto de la
aplicación), la vista queda, automáticamente, actualizada. Por lo
tanto, ya no tienes que repetir la consulta de selección para
recuperar los nuevos datos de la tabla. Sólo tienes que mirar en
la vista, que tienen todos los datos de la consulta original
actualizados en tiempo real.
Sintaxis:
CREATE [OR REPLACE] VIEW nombre_vista [lista_columnas]
AS consulta
En donde:
nombre_vista: Representa el nombre de la tabla virtual que tendrá
la vista.
lista_columnas: Es el listado de columnas que creará la vista.
consulta: Se trata de una consulta SELECT que nos devuelven los
datos que forman de la vista.
También podemos ver el modificador opcional OR REPLACE. Cuando se
crea una vista con OR REPLACE, se creará la vista si no existe
una con el mismo nombre y, si existe, se reemplazará por ésta.

Que ventaja tenemos:


La mayor ventaja de utilizar vistas se obtiene en forma de
rendimiento, ya que no estaremos generando constantemente una
vista si ésta ya existe. Cuanto más complejas sean las consultas
que se deben ejecutar para obtener la vista, mayor será la ganancia
de rendimiento. Por otro lado, también puede suponer una ventaja
en términos de seguridad si no queremos que los usuarios puedan
obtener datos de las tablas originales sobre las que se crea la
vista.

También podemos limitar los permisos de acceso a una vista a


ciertos usuarios. Una vista, en general, puede ayudarte a
construir una interfaz simplificada y abstracta a una base de
datos compleja.
Creando una vista sencilla:
CREATE VIEW vista0 AS
select * from productos
Cuando crees una vista, podrás ejecutar consultas sobre ella como
si de una tabla más se tratase. Por ejemplo, vamos a seleccionar
todos los datos de la vista.
Select * from vista0;
Borrando una vista:
Puedes eliminar una vista haciendo uso de la sentencia DROP VIEW.
Por ejemplo, si quieres eliminar la vista: vista0
DROP VIEW vista0;

PROCEDIMIENTOS ALMACENADOS

Un procedimiento almacenado MySQL no es más que una porción de


código que puedes guardar y reutilizar. Es útil cuando repites la
misma tarea repetidas veces, siendo un buen método para encapsular
el código. Al igual que ocurre con las funciones, también puede
aceptar datos como parámetros, de modo que actúa en base a éstos.

Para poder crear un procedimiento almacenado es necesario que


tengas permisos INSERT y DELETE sobre la base de datos.
La sintaxis de un procedimiento almacenado es la siguiente:

CREATE PROCEDURE nombre_procedimiento


AS
sentencias_sql
GO;

Para ejecutar un procedimiento almacenado lo invocamos así:

EXEC nombre_procedimiento (param1, param2, ....);

Parámetros:

Como has visto, los parámetros se definen separados por una coma.
Los parámetros de los procedimientos almacenados de MySQL pueden
ser de tres tipos:

IN: Es el tipo de parámetro que se usa por defecto. La aplicación


o código que invoque al procedimiento tendrá que pasar un argumento
para este parámetro. El procedimiento trabajará con una copia de
su valor, teniendo el parámetro su valor original al terminar la
ejecución del procedimiento.
OUT: El valor de este parámetro puEde ser cambiado en el
procedimiento, y además su valor modificado será enviado de vuelta
al código o programa que invoca el procedimiento.
INOUT: Es una mezcla de los dos conceptos anteriores. La aplicación
o código que invoca al procedimiento puede pasarle un valor a éste,
devolviendo el valor modificado al terminar la ejecución. En caso
de resultarte confuso, echa un ojo al ejemplo que verás más
adelante.

CREATE TABLE productos (


id INT NOT NULL AUTO_INCREMENT,
nombre VARCHAR(20) NOT NULL,
estado VARCHAR(20) NOT NULL DEFAULT 'disponible',
precio FLOAT NOT NULL DEFAULT 0.0,
PRIMARY KEY(id)
);
Ahora vamos a insertar algunos datos de prueba en la tabla
productos:

INSERT INTO productos (nombre, estado, precio) VALUES ('Producto


A','disponible', 8),

Ahora que hemos configurado una base de datos y una tabla, vamos
a crear tres procedimientos almacenados para mostrar el uso y las
diferencias de cada tipo de parámetro.

Al definir los procedimientos, tendremos que usar delimitadores


para indicar a MySQL que se trata de un bloque independiente. En
los siguientes ejemplos, DELIMITER $$ frena la ejecución de MySQL,
que se retomará de nuevo en la sentencia DELIMITER del final.
Vamos a obtener los productos que tienen un determinado estado.
Para crear el procedimiento, ejecuta estas sentencias SQL:

DELIMITER $$
CREATE PROCEDURE obtenerProductosPorEstado(IN nombre_estado
VARCHAR(255))
BEGIN
SELECT *
FROM productos
WHERE estado = nombre_estado;
END$$
DELIMITER
El nombre del estado está contenido en el parámetro nombre_estado
que hemos definido como IN. Suponiendo que quieras obtener los
productos con estado disponible, tendrías que invocar al
procedimiento de este modo:

CALL obtenerProductosPorEstado('disponible')

Cursores
Los cursores le permiten iterar los resultados de la consulta uno
por línea. DECLARE comando DECLARE se usa para iniciar el cursor
y asociarlo con una consulta SQL específica:

DECLARE student CURSOR FOR SELECT name FROM studend;


Digamos que vendemos productos de algunos tipos. Queremos contar
cuántos productos de cada tipo existen.

Nuestros datos:

CREATE TABLE product


(
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(50) NOT NULL,
name VARCHAR(255) NOT NULL

);
CREATE TABLE product_type
(
name VARCHAR(50) NOT NULL PRIMARY KEY
);
CREATE TABLE product_type_count
(
type VARCHAR(50) NOT NULL PRIMARY KEY,
count INT(10) UNSIGNED NOT NULL DEFAULT 0
);
INSERT INTO product_type (name) VALUES
('dress'),
('food');

INSERT INTO product (type, name) VALUES


('dress', 'T-shirt'),
('dress', 'Trousers'),
('food', 'Apple'),
('food', 'Tomatoes'),
('food', 'Meat');
Podemos lograr el objetivo usando el procedimiento almacenado
usando el cursor:

DELIMITER //
DROP PROCEDURE IF EXISTS product_count;
CREATE PROCEDURE product_count()
BEGIN
DECLARE p_type VARCHAR(255);
DECLARE p_count INT(10) UNSIGNED;
DECLARE done INT DEFAULT 0;
DECLARE product CURSOR FOR
SELECT
type,
COUNT(*)
FROM product
GROUP BY type;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

TRUNCATE product_type;

OPEN product;

REPEAT
FETCH product
INTO p_type, p_count;
IF NOT done
THEN
INSERT INTO product_type_count
SET
type = p_type,
count = p_count;
END IF;
UNTIL done
END REPEAT;

CLOSE product;
END //
DELIMITER;

También podría gustarte