Mes: junio 2018
Ejemplo trigger
CREATE TABLE `customer_log` ( `idcustomer_log` int(11) NOT NULL AUTO_INCREMENT, `customer_id` int(11) DEFAULT NULL, `user` varchar(45) DEFAULT NULL, `fecha` datetime DEFAULT NULL, `nombre` varchar(45) DEFAULT NULL, `nombre_ant` varchar(45) DEFAULT NULL, PRIMARY KEY (`idcustomer_log`) ) DELIMITER // CREATE TRIGGER cliente_actualizado BEFORE UPDATE ON customer FOR EACH ROW BEGIN DECLARE vUser varchar(50); -- Find username of person performing the INSERT into table SELECT USER() INTO vUser; -- Insert record into audit table INSERT INTO customer_log ( customer_id, fecha, user,nombre,nombre_ant) VALUES ( NEW.customer_id, SYSDATE(), vUser,NEW.first_name, OLD.first_name ); END;// DELIMITER ;
Ejemplos desencadenadores (triggers)
Al borrar:
CREATE TRIGGER `sakila`.`actor_BEFORE_DELETE` BEFORE DELETE ON `actor` FOR EACH ROW BEGIN if OLD.actor_id between 1 and 20 then SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No puedes borrar'; else insert into actor_log(first_name, last_name) values (OLD.first_name, OLD.last_name); end if; END
Al insertar:
CREATE DEFINER=`root`@`localhost` TRIGGER `sakila`.`payment_BEFORE_INSERT` BEFORE INSERT ON `payment` FOR EACH ROW BEGIN if NEW.amount>=10 then set NEW.amount=9.99; end if; END
Al modificar:
CREATE DEFINER=`root`@`localhost` TRIGGER `sakila`.`payment_BEFORE_UPDATE` BEFORE UPDATE ON `payment` FOR EACH ROW BEGIN if NEW.amount > OLD.amount then set NEW.amount=OLD.amount; end if; END
Instrucciones de programación en MySql
Ejercicios Northwind
Insertar en Customers la compañía ‘Compañía XX’ con ‘Ana’, ‘Pi’ como contacto
insert into customers (company,first_name,last_name) values ('Compañía XX','Ana','Pi')
Modificar en Customer el campo email_address y poner ‘Sin email’
update customers set email_address='Sin email'
Eliminar el Customer con id = 20
delete from customers where id=20
Seleccionar todos los proveedores (suppliers) cuyo trabajo sea ‘Sales Manager’
SELECT * from suppliers where job_title='Sales manager'
Seleccionar todos los pedidos (orders) de junio
select * from orders where month(order_date)=6
Calcular el número de pedidos por cliente
SELECT company,count(orders.id) total FROM customers left join orders on customers.id=orders.customer_id group by customers.id
Calcular el total de ventas por empleado
SELECT last_name,first_name,sum(quantity*unit_price*(1-discount)) total FROM employees join orders on employees.id=orders.employee_id join order_details on orders.id=order_details.order_id group by employees.id
Averiguar el producto más caro
SELECT * FROM `products` order by list_price desc limit 1
Averiguar el número de ventas por producto
select products.*, sum(quantity*unit_price*(1-discount)) total from products join order_details on products.id= order_details.product_id group by products.id
Mostrar los clientes con más de 10000 en ventas
select customers.*, sum(quantity*unit_price*(1-discount)) total from customers join orders on customers.id= orders.customer_id join order_details on orders.id= order_details.order_id group by customers.id having total>10000
BD Northwind
Crear joins en base de datos
index.php:
<h1>Camino entre tablas</h1> Escoja tabla: <form> <select name="bd"> <?php $user = 'root'; $pass = ''; $server = 'localhost'; $dbh = new PDO("mysql:host=$server", $user, $pass); $dbs = $dbh->query('SHOW DATABASES'); while (( $db = $dbs->fetchColumn(0) ) !== false) { echo "<option>".$db . '</option>'; } ?> </select> <input type="submit" value="Enviar"></form> <?php if (!empty($_GET['bd'])){ ?> <p>Seleccione las tablas origen y fin</p> <form action="camino.php"> <input type="hidden" name="bd" value="<?=$_GET['bd']?>"> <label>Origen:</label> <select name="origen"> <?php $dbs = $dbh->query('USE '.$_GET['bd']); $dbs = $dbh->query('SHOW TABLES'); while (( $db = $dbs->fetchColumn(0) ) !== false) { echo "<option>".$db . '</option>'; } ?> </select> <label>Fin:</label> <select name="fin"><?php $dbs = $dbh->query('USE '.$_GET['bd']); $dbs = $dbh->query('SHOW TABLES'); while (( $db = $dbs->fetchColumn(0) ) !== false) { echo "<option>".$db . '</option>'; } ?></select> <input type="submit" value="Enviar"> </form> <?php }
camino.php
<?php $bd = $_GET['bd']; $origen = $_GET['origen']; $fin = $_GET['fin']; $user = 'root'; $pass = ''; $server = 'localhost'; $dbh = new PDO("mysql:host=$server", $user, $pass); $dbs = $dbh->query('use ' . $bd); $tablas = getTables($dbh); $tablas = setFKPaths($tablas, $dbh, $bd); $caminos = []; buscarCamino($origen, $fin, $origen, 0); usort($caminos, function($a, $b) { return strlen($a) - strlen($b); }); foreach ($caminos as $camino) { $camino = explode(",", $camino); echo "<h4>select * from " . $camino[0]; for ($i = 1; $i < count($camino); $i++) { $c = explode("/", $camino[$i]); echo " join " . $c[0] . " using (" . $c[1] . ")<br/>"; } echo "</h4>"; } function getTables($dbh) { $tablas = []; $dbs = $dbh->query('SHOW TABLES'); while (( $db = $dbs->fetchColumn(0) ) !== false) { $tablas[$db] = []; } return $tablas; } function setFKPaths($tablas, $dbh, $bd) { $dbs = $dbh->query("select * from information_schema.INNODB_SYS_FOREIGN where id like '$bd%'"); $fks = $dbs->fetchAll(); foreach ($fks as $fk) { $dbs = $dbh->query("select * from information_schema.INNODB_SYS_FOREIGN_COLS where id = '$fk[0]'"); $fc = $dbs->fetchAll(); $t1 = explode("/", $fk[1])[1]; $t2 = explode("/", $fk[2])[1]; $k = $fc[0][1]; if (!in_array($t1 . "/" . $k, $tablas[$t2])) { $tablas[$t2][] = $t1 . "/" . $k; } if (!in_array($t2 . "/" . $k, $tablas[$t1])) { $tablas[$t1][] = $t2 . "/" . $k; } } return $tablas; } function buscarCamino($inicio, $fin, $camino, $prof) { global $caminos; global $tablas; if ($inicio == $fin) { $caminos[] = $camino; return; } foreach ($tablas[$inicio] as $destino) { $d = explode("/", $destino)[0]; if (strpos($camino, "," . $d . "/") === false && strpos($camino, $d . ",") === false) { buscarCamino($d, $fin, $camino . "," . $destino, $prof + 1); } } }
Ejemplos subqueries
Pagos por encima de la media:
select * from payment where amount>( select avg(amount) from payment )
Películas de la categoría 1:
select distinct first_name,last_name from actor join film_actor using(actor_id) where film_id in ( select film_id from film_category where category_id=1 )
Películas con el mayor coste de reemplazo:
select * from film where replacement_cost=( select max(replacement_cost) from film )
Películas de la categoría con más alquileres:
select * from film join film_category using(film_id) where category_id in ( select category_id from category join film_category using(category_id) join film using(film_id) join inventory using(film_id) join rental using(inventory_id) group by category_id having count(rental_id)=( select max(total) from ( select count(rental_id) total from category join film_category using(category_id) join film using(film_id) join inventory using(film_id) join rental using(inventory_id) group by category_id ) alias_falso ) )
Tutorial mysql
Categorías – países
SELECT
country, name
FROM
category
JOIN
film_category ON category.category_id = film_category.category_id
JOIN
film ON film.film_id = film_category.film_id
JOIN
inventory ON film.film_id = inventory.film_id
JOIN
store ON inventory.store_id = store.store_id
JOIN
customer ON store.store_id = customer.store_id
JOIN
address ON address.address_id = customer.address_id
JOIN
city ON city.city_id = address.city_id
JOIN
country ON country.country_id = city.country_id