Oracle_One-Alura_Latam/011_mysql/consultas_sql.md
2023-10-29 03:55:17 -03:00

74 KiB
Raw Permalink Blame History

Consultas SQL

Avanzando en SQL con MySQL

Importar tablas de ejemplo

alura-repo

WARNING: Cambiar COLLATE de utf8mb4_0900_ai_ci a uca1400_as_ci

USE jugos_ventas;

Consutas

DESC tabla_de_clientes;

+---------------------+--------------+------+-----+---------+-------+
| Field               | Type         | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| DNI                 | varchar(11)  | NO   | PRI | NULL    |       |
| NOMBRE              | varchar(100) | YES  |     | NULL    |       |
| DIRECCION_1         | varchar(150) | YES  |     | NULL    |       |
| DIRECCION_2         | varchar(150) | YES  |     | NULL    |       |
| BARRIO              | varchar(50)  | YES  |     | NULL    |       |
| CIUDAD              | varchar(50)  | YES  |     | NULL    |       |
| ESTADO              | varchar(2)   | YES  |     | NULL    |       |
| CP                  | varchar(8)   | YES  |     | NULL    |       |
| FECHA_DE_NACIMIENTO | date         | YES  |     | NULL    |       |
| EDAD                | smallint(6)  | YES  |     | NULL    |       |
| SEXO                | varchar(1)   | YES  |     | NULL    |       |
| LIMITE_DE_CREDITO   | float        | YES  |     | NULL    |       |
| VOLUMEN_DE_COMPRA   | float        | YES  |     | NULL    |       |
| PRIMERA_COMPRA      | bit(1)       | YES  |     | NULL    |       |
+---------------------+--------------+------+-----+---------+-------+
14 rows in set (0.005 sec)

Consultar todos los datos

SELECT dni, nombre, direccion_1, direccion_2, barrio, ciudad, estado, cp,
fecha_de_nacimiento, edad, sexo, limite_de_credito, volumen_de_compra,
primera_compra

El equivalente sería SELECT * FROM tabla_de_clientes;

Consultar algunos datos

SELECT dni, nombre FROM tabla_de_clientes;

SELECT dni AS Identificacion, nombre AS Cliente FROM tabla_de_clientes;

SELECT * FROM tabla_de_productos WHERE SABOR = 'Uva';

SELECT * FROM tabla_de_productos WHERE precio_de_lista < 16;
SELECT * FROM tabla_de_productos WHERE precio_de_lista > 16;
SELECT * FROM tabla_de_productos WHERE precio_de_lista BETWEEN 16 AND 16.02;

Consultas condicionales

Operadores SQL

Operadores lógicos

Operator Description
ALL TRUE if all of a set of comparisons are TRUE
AND TRUE if all the conditions separated by AND are TRUE
ANY TRUE if any one of a set of comparisons are TRUE
BETWEEN TRUE if the operand lies within the range of comparisons
EXISTS TRUE if the subquery returns one or more records
IN TRUE if the operand is equal to one of a list of expressions
LIKE TRUE if the operand matches a pattern specially with wildcard
NOT Reverses the value of any other Boolean operator
OR TRUE if any of the conditions separated by OR is TRUE
IS NULL TRUE if the expression value is NULL
SOME TRUE if some of a set of comparisons are TRUE
UNIQUE The UNIQUE operator searches every row of a specified table for uniqueness (no duplicates)
  • Operación OR: El resultado de la operación es verdadero si alguna de sus condiciones es verdadera
  • Operación AND: El resultado de la operación es verdadero si todas sus condiciones es verdadera
  • Operación NOR(NOT OR): Negación de la operación OR
  • Operación NAND(NOT AND): Negación de la operación AND
Verdadero Falso
1 0
A B OR AND NOR NAND
0 0 0 0 1 1
0 1 1 0 0 1
1 0 1 0 0 1
1 1 1 1 0 0

Operadores de comparación

Operadores Descripción
= Equal to
!= Not equal
<> Not equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
!< Not less than
!> Not greater than

Ejemplo

A B A=B A<=B
3 5 0 1
5 23 0 1
7 7 1 1
2 70 0 1
87 85 0 0
69 43 0 0
21 1 0 0
4 2 0 0
9 9 1 1
NOT ((V AND F) OR NOT (F OR F))
NOT ((F) OR NOT (F))
NOT (F OR V)
NOT (V)
F

¿La sgte. expresión es Falsa o Verdadera?

(NOT ((3 > 2) OR (4 >= 5)) AND (5 > 4) ) OR (9 > 0)

Respuesta

(NOT ((3 > 2) OR (4 >= 5)) AND (5 > 4) ) OR (9 > 0)
(NOT ((V) OR (F)) AND (V) ) OR (V)
(NOT V AND V ) OR V
(NOT F) OR V
V OR V
V

Creación de consultas condicionales

SELECT * FROM tabla_de_productos WHERE sabor='mango' AND tamano='470 ml';
+---------+--------+--------+-------+-------------------+------+
| 1078680 | Verano | 470 ml | Mango | Botella de Vidrio | 5.18 |
+---------+--------+--------+-------+-------------------+------+
SELECT * FROM tabla_de_productos WHERE sabor='mango' OR tamano='470 ml';
+---------------------+---------------------+------------+---------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR   | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+---------+-------------------+-----------------+
| 1051518             | Verano              | 470 ml     | Limón   | Botella de Vidrio |             3.3 |
| 1078680             | Verano              | 470 ml     | Mango   | Botella de Vidrio |            5.18 |
| 1086543             | Refrescante         | 1 Litro    | Mango   | Botella PET       |           11.01 |
...
SELECT * FROM tabla_de_productos WHERE NOT(sabor='mango') OR tamano='470 ml';
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR           | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| 1000889             | Sabor da Montaña    | 700 ml     | Uva             | Botella de Vidrio |            6.31 |
| 1002334             | Línea Citrus        | 1 Litro    | Lima/Limón      | Botella PET       |               7 |
| 1002767             | Vida del Campo      | 700 ml     | Cereza/Manzana  | Botella de Vidrio |            8.41 |
| 1004327             | Vida del Campo      | 1,5 Litros | Sandía          | Botella PET       |           19.51 |
...
SELECT * FROM tabla_de_productos WHERE NOT(sabor='mango' OR tamano='470 ml');
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR           | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| 1000889             | Sabor da Montaña    | 700 ml     | Uva             | Botella de Vidrio |            6.31 |
| 1002334             | Línea Citrus        | 1 Litro    | Lima/Limón      | Botella PET       |               7 |
| 1002767             | Vida del Campo      | 700 ml     | Cereza/Manzana  | Botella de Vidrio |            8.41 |
| 1004327             | Vida del Campo      | 1,5 Litros | Sandía          | Botella PET       |           19.51 |
...
SELECT * FROM tabla_de_productos WHERE NOT(sabor='mango' AND tamano='470 ml');
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR           | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+-----------------+-------------------+-----------------+
| 1000889             | Sabor da Montaña    | 700 ml     | Uva             | Botella de Vidrio |            6.31 |
| 1002334             | Línea Citrus        | 1 Litro    | Lima/Limón      | Botella PET       |               7 |
| 1002767             | Vida del Campo      | 700 ml     | Cereza/Manzana  | Botella de Vidrio |            8.41 |
| 1004327             | Vida del Campo      | 1,5 Litros | Sandía          | Botella PET       |           19.51 |
| 1013793             | Vida del Campo      | 2 Litros   | Cereza/Manzana  | Botella PET       |           24.01 |
...
SELECT * FROM tabla_de_productos WHERE sabor='mango' AND NOT (tamano='470 ml');
+---------------------+---------------------+------------+-------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+-------+-------------------+-----------------+
| 1086543             | Refrescante         | 1 Litro    | Mango | Botella PET       |           11.01 |
| 1096818             | Refrescante         | 700 ml     | Mango | Botella de Vidrio |            7.71 |
| 235653              | Verano              | 350 ml     | Mango | Lata              |            3.86 |
| 326779              | Refrescante         | 1,5 Litros | Mango | Botella PET       |           16.51 |
+---------------------+---------------------+------------+-------+-------------------+-----------------+

IN

SELECT * FROM tabla_de_productos WHERE sabor IN ('mango', 'uva');
+---------------------+---------------------+------------+-------+-------------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR | ENVASE            | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+-------+-------------------+-----------------+
| 1000889             | Sabor da Montaña    | 700 ml     | Uva   | Botella de Vidrio |            6.31 |
| 1078680             | Verano              | 470 ml     | Mango | Botella de Vidrio |            5.18 |
| 1086543             | Refrescante         | 1 Litro    | Mango | Botella PET       |           11.01 |
| 1096818             | Refrescante         | 700 ml     | Mango | Botella de Vidrio |            7.71 |
| 235653              | Verano              | 350 ml     | Mango | Lata              |            3.86 |
| 326779              | Refrescante         | 1,5 Litros | Mango | Botella PET       |           16.51 |
+---------------------+---------------------+------------+-------+-------------------+-----------------+
SELECT nombre, direccion_1, ciudad, fecha_de_nacimiento as nacimiento, edad
    FROM tabla_de_clientes 
    WHERE ciudad IN ('ciudad de México', 'Guadalajara')
    AND (edad BETWEEN 20 AND 25);
+----------------+-----------------------------+-------------------+------------+------+
| NOMBRE         | DIRECCION_1                 | CIUDAD            | NACIMIENTO | EDAD |
+----------------+-----------------------------+-------------------+------------+------+
| Abel Pintos    | Carr. México-Toluca 1499    | Ciudad de México  | 1995-06-11 |   25 |
| Joana Olivera  | Pachuca 75                  | Ciudad de México  | 1995-02-14 |   25 |
| Luis Silva     | Prol. 16 de Septiembre 1156 | Ciudad de México  | 1995-04-07 |   25 |
| Edson Calisaya | Sta Úrsula Xitla            | Ciudad de México  | 1995-01-07 |   25 |
+----------------+-----------------------------+-------------------+------------+------+

LIKE

SELECT * FROM tb WHERE campo LIKE ´%<condición´;
  • <condición> el texto utilizado
  • % Representa cualquier registro genérico antes de la condición (comodín)

Ejemplo

NOMBRE
Miguel Suárez Diaz
Raul José Suárez
Manuela Diaz Avendaño
Mario García Rojas
Carlos Santiago Pérez
Daniela Suárez
Pedro González
Pablo Restrepo Villa
José Manuel Sánchez
SELECT * FROM tb WHERE campo LIKE ´%suárez%´;

Retornaría: Miguel Suárez Diaz, Raul José Suárez y Daniela Suárez

SELECT * FROM tb WHERE campo LIKE ´%suárez´;

Retornaría: Raul José Suárez y Daniela Suárez

SELECT * FROM tabla_de_productos WHERE sabor LIKE '%manzana%' AND envase = 'botella pet';
+---------------------+---------------------+------------+----------------+-------------+-----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR          | ENVASE      | PRECIO_DE_LISTA |
+---------------------+---------------------+------------+----------------+-------------+-----------------+
| 1013793             | Vida del Campo      | 2 Litros   | Cereza/Manzana | Botella PET |           24.01 |
| 520380              | Pedazos de Frutas   | 1 Litro    | Manzana        | Botella PET |           12.01 |
| 788975              | Pedazos de Frutas   | 1,5 Litros | Manzana        | Botella PET |           18.01 |
+---------------------+---------------------+------------+----------------+-------------+-----------------+

DISTINCT

Devuelve solo registros con valores diferentes

CAMPO_1 CAMPO_2
A B
Z C
Z Q
A B
E R
T E
Z C
Z Q
T E
SELECT DISTINCT * FROM tb;

Retorna:

CAMPO_1 CAMPO_2
A B
Z C
Z Q
E R
T E
SELECT DISTINCT envase, tamano FROM tabla_de_productos;
+-------------------+------------+
| envase            | tamano     |
+-------------------+------------+
| Botella de Vidrio | 700 ml     |
| Botella PET       | 1 Litro    |
| Botella PET       | 1,5 Litros |
| Botella PET       | 2 Litros   |
| Lata              | 350 ml     |
| Botella de Vidrio | 470 ml     |
+-------------------+------------+
SELECT DISTINCT envase, tamano, sabor FROM tabla_de_productos
    -> WHERE sabor = 'naranja';
+-------------------+------------+---------+
| envase            | tamano     | sabor   |
+-------------------+------------+---------+
| Botella PET       | 2 Litros   | Naranja |
| Botella de Vidrio | 470 ml     | Naranja |
| Botella PET       | 1 Litro    | Naranja |
| Lata              | 350 ml     | Naranja |
| Botella PET       | 1,5 Litros | Naranja |
+-------------------+------------+---------+

LIMIT

Limita el númeo de registros devueltos

Ejm. limitar a 3 resultados

SELECT * FROM tb LIMIT 3;

Ejm. limitar a 3 resultados, a partir de indice 2

SELECT * FROM tb LIMIT 2,2;
SELECT codigo_del_producto, nombre_del_producto, tamano, sabor 
    FROM tabla_de_productos
    LIMIT 5;
+---------------------+---------------------+------------+----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR          |
+---------------------+---------------------+------------+----------------+
| 1000889             | Sabor da Montaña    | 700 ml     | Uva            |
| 1002334             | Línea Citrus        | 1 Litro    | Lima/Limón     |
| 1002767             | Vida del Campo      | 700 ml     | Cereza/Manzana |
| 1004327             | Vida del Campo      | 1,5 Litros | Sandía         |
| 1013793             | Vida del Campo      | 2 Litros   | Cereza/Manzana |
+---------------------+---------------------+------------+----------------+
SELECT codigo_del_producto, nombre_del_producto, tamano, sabor 
    FROM tabla_de_productos
    LIMIT 2,5;
+---------------------+---------------------+------------+----------------+
| CODIGO_DEL_PRODUCTO | NOMBRE_DEL_PRODUCTO | TAMANO     | SABOR          |
+---------------------+---------------------+------------+----------------+
| 1002767             | Vida del Campo      | 700 ml     | Cereza/Manzana |
| 1004327             | Vida del Campo      | 1,5 Litros | Sandía         |
| 1013793             | Vida del Campo      | 2 Litros   | Cereza/Manzana |
| 1022450             | Festival de Sabores | 2 Litros   | Asái           |
| 1037797             | Clean               | 2 Litros   | Naranja        |
+---------------------+---------------------+------------+----------------+
SELECT * FROM facturas WHERE fecha_venta = '2017/01/01' LIMIT 10;
+-------------+-----------+-------------+--------+----------+
| DNI         | MATRICULA | FECHA_VENTA | NUMERO | IMPUESTO |
+-------------+-----------+-------------+--------+----------+
| 9283760794  | 00235     | 2017-01-01  |  54476 |     0.12 |
| 50534475787 | 00237     | 2017-01-01  |  54477 |     0.12 |
| 492472718   | 00235     | 2017-01-01  |  54478 |     0.12 |
| 3623344710  | 00235     | 2017-01-01  |  54479 |     0.12 |
| 94387575700 | 00236     | 2017-01-01  |  54480 |      0.1 |
| 94387575700 | 00235     | 2017-01-01  |  54481 |     0.12 |
| 9283760794  | 00237     | 2017-01-01  |  54482 |      0.1 |
| 2600586709  | 00235     | 2017-01-01  |  54483 |      0.1 |
| 9283760794  | 00235     | 2017-01-01  |  54484 |      0.1 |
| 5576228758  | 00237     | 2017-01-01  |  54485 |     0.12 |
+-------------+-----------+-------------+--------+----------+

ORDER BY

SELECT codigo_del_producto AS codigo,
       nombre_del_producto AS nombre,
       precio_de_lista AS precio
    FROM tabla_de_productos
    ORDER BY precio_de_lista DESC
    DESC LIMIT 10;
+---------+---------------------+--------+
| codigo  | nombre              | precio |
+---------+---------------------+--------+
| 1022450 | Festival de Sabores |  38.01 |
| 695594  | Festival de Sabores |  28.51 |
| 1013793 | Vida del Campo      |  24.01 |
| 746596  | Light               |  19.51 |
| 1004327 | Vida del Campo      |  19.51 |
| 788975  | Pedazos de Frutas   |  18.01 |
| 326779  | Refrescante         |  16.51 |
| 1037797 | Clean               |  16.01 |
| 231776  | Festival de Sabores |  13.31 |
| 838819  | Clean               |  12.01 |
+---------+---------------------+--------+
SELECT codigo_del_producto AS codigo,
       nombre_del_producto AS nombre,
       precio_de_lista AS precio
    FROM tabla_de_productos
    ORDER BY precio_de_lista ASC,
             nombre_del_producto DESC
    DESC LIMIT 10;
+---------+-------------------+--------+
| codigo  | nombre            | precio |
+---------+-------------------+--------+
| 544931  | Verano            |   2.46 |
| 812829  | Clean             |   2.81 |
| 1051518 | Verano            |    3.3 |
| 479745  | Clean             |   3.77 |
| 235653  | Verano            |   3.86 |
| 229900  | Pedazos de Frutas |   4.21 |
| 290478  | Vida del Campo    |   4.56 |
| 1040107 | Light             |   4.56 |
| 1041119 | Línea Citrus      |    4.9 |
| 1042712 | Línea Citrus      |    4.9 |
+---------+-------------------+--------+

¿Cuál (o cuáles) fue (fueron) la(s) mayor(es) venta(s) del producto “Refrescante, 1 Litro, Frutilla/Limón”, en cantidad?

SELECT numero, codigo_del_producto, cantidad, precio, cantidad*precio as total
    FROM items_facturas WHERE codigo_del_producto IN (
        SELECT codigo_del_producto
            FROM tabla_de_productos 
            WHERE nombre_del_producto = 'refrescante'
                AND tamano = '1 litro'
                AND sabor = 'frutilla/limón'
    )
ORDER BY total DESC LIMIT 10;
+--------+---------------------+----------+---------+--------------------+
| numero | codigo_del_producto | cantidad | precio  | total              |
+--------+---------------------+----------+---------+--------------------+
|  83710 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  85301 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  87424 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  84674 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  85905 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  83818 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  84389 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  87209 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  81740 | 1101035             |       99 | 10.6324 | 1052.6075563430786 |
|  81765 | 1101035             |       98 | 10.6324 | 1041.9751567840576 |
+--------+---------------------+----------+---------+--------------------+

Analisis de la query

ANALYZE SELECT numero, codigo_del_producto, cantidad, precio, cantidad*precio as total
    FROM items_facturas WHERE codigo_del_producto IN (
        SELECT codigo_del_producto
            FROM tabla_de_productos 
            WHERE nombre_del_producto = 'refrescante'
                AND tamano = '1 litro'
                AND sabor = 'frutilla/limón'
    )
ORDER BY total DESC LIMIT 10;

+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+---------+----------+------------+----------------------------------------------+
| id   | select_type | table              | type | possible_keys       | key                 | key_len | ref                                                 | rows | r_rows  | filtered | r_filtered | Extra                                        |
+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+---------+----------+------------+----------------------------------------------+
|    1 | PRIMARY     | tabla_de_productos | ALL  | PRIMARY             | NULL                | NULL    | NULL                                                | 35   | 35.00   |   100.00 |       2.86 | Using where; Using temporary; Using filesort |
|    1 | PRIMARY     | items_facturas     | ref  | CODIGO_DEL_PRODUCTO | CODIGO_DEL_PRODUCTO | 42      | jugos_ventas.tabla_de_productos.CODIGO_DEL_PRODUCTO | 2743 | 7103.00 |   100.00 |     100.00 |                                              |
+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+---------+----------+------------+----------------------------------------------+
DESCRIBE SELECT numero, codigo_del_producto, cantidad, precio, cantidad*precio as total
    FROM items_facturas WHERE codigo_del_producto IN (
        SELECT codigo_del_producto
            FROM tabla_de_productos 
            WHERE nombre_del_producto = 'refrescante'
                AND tamano = '1 litro'
                AND sabor = 'frutilla/limón'
    )
ORDER BY total DESC LIMIT 10;
+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+----------------------------------------------+
| id   | select_type | table              | type | possible_keys       | key                 | key_len | ref                                                 | rows | Extra                                        |
+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+----------------------------------------------+
|    1 | PRIMARY     | tabla_de_productos | ALL  | PRIMARY             | NULL                | NULL    | NULL                                                | 35   | Using where; Using temporary; Using filesort |
|    1 | PRIMARY     | items_facturas     | ref  | CODIGO_DEL_PRODUCTO | CODIGO_DEL_PRODUCTO | 42      | jugos_ventas.tabla_de_productos.CODIGO_DEL_PRODUCTO | 2743 |                                              |
+------+-------------+--------------------+------+---------------------+---------------------+---------+-----------------------------------------------------+------+----------------------------------------------+

GROUP BY

X Y
A 3
Z 5
Z 1
A 1
E 4
T 3
Z 8
Z 2
T 1
SELECT x, SUM(y) FROM tb GROUP BY X;
X Y
A 4
E 4
T 4
Z 16
SELECT x, SUM(y) FROM tb;
28

Funciones

Omitiendo el campo de agregación la operación se realiza sobre toda la tabla

Funcion Operación
SUM() Suma
MAX() Máximo
MIN() Mínimo
AVG() Promedio
COUNT() Contador

MAX

SELECT x, MAX(y) FROM tb GROUP BY X;
X Y
A 3
E 4
T 3
Z 8
SELECT x, MAX(y) FROM tb;
8

MIN

SELECT x, MIN(y) FROM tb GROUP BY X;
X Y
A 1
E 4
T 1
Z 1
SELECT x, MIN(y) FROM tb;
1

AVG

SELECT x, AVG(y) FROM tb GROUP BY X;
X Y
A 2
E 4
T 2
Z 4
SELECT x, AVG(y) FROM tb GROUP BY X;
3.111

COUNT

SELECT x, COUNT(y) FROM tb GROUP BY X;
X Y
A 2
E 1
T 2
Z 4
SELECT x, COUNT(y) FROM tb;
9

Pruebas en la BD

SELECT estado, SUM(limite_de_credito) AS limite_total
    FROM tabla_de_clientes
    GROUP BY estado;
+--------+--------------+
| estado | limite_total |
+--------+--------------+
| EM     |      1495000 |
| JC     |       285000 |
+--------+--------------+
SELECT envase, MAX(precio_de_lista) AS precio_mayor
    FROM tabla_de_productos
    GROUP BY envase;
+-------------------+--------------+
| envase            | precio_mayor |
+-------------------+--------------+
| Botella de Vidrio |        13.31 |
| Botella PET       |        38.01 |
| Lata              |         4.56 |
+-------------------+--------------+
SELECT envase, COUNT(*)
    FROM tabla_de_productos
    GROUP BY envase;
+-------------------+----------+
| envase            | COUNT(*) |
+-------------------+----------+
| Botella de Vidrio |       13 |
| Botella PET       |       16 |
| Lata              |        6 |
+-------------------+----------+
SELECT barrio, SUM(limite_de_credito) AS limite
    FROM tabla_de_clientes
    WHERE ciudad = 'ciudad de méxico'
    GROUP BY barrio;
+-------------------------+--------+
| barrio                  | limite |
+-------------------------+--------+
| Barrio del Niño Jesús   | 150000 |
| Carola                  | 120000 |
| Condesa                 |  70000 |
| Contadero               | 110000 |
| Cuajimalpa              | 170000 |
| Del Valle               | 420000 |
| Ex Hacienda Coapa       |  60000 |
| Floresta Coyoacán       | 200000 |
| Héroes de Padierna      | 120000 |
| Locaxco                 |  75000 |
+-------------------------+--------+
SELECT estado, barrio, MAX(limite_de_credito) AS limite, edad
    FROM tabla_de_clientes
    WHERE edad >= 20
    GROUP BY estado, barrio
    ORDER BY edad;
+--------+-------------------------+--------+------+
| estado | barrio                  | limite | edad |
+--------+-------------------------+--------+------+
| EM     | Contadero               | 110000 |   25 |
| EM     | Condesa                 |  70000 |   25 |
| EM     | Cuajimalpa              | 170000 |   25 |
| EM     | Barrio del Niño Jesús   | 150000 |   25 |
| JC     | Barragán Hernández      | 120000 |   26 |
| EM     | Locaxco                 |  75000 |   26 |
| JC     | Oblatos                 |  75000 |   26 |
| EM     | Carola                  | 120000 |   29 |
| EM     | Héroes de Padierna      | 120000 |   29 |
| EM     | Del Valle               | 170000 |   30 |
| EM     | Ex Hacienda Coapa       |  60000 |   31 |
| EM     | Floresta Coyoacán       | 200000 |   37 |
+--------+-------------------------+--------+------+

¿ Cuantas facturas existen que tengan la mayor cantidad del producto '1101035' ?

SELECT COUNT(*) FROM items_facturas
    WHERE cantidad=(
        SELECT MAX(CANTIDAD)
        FROM items_facturas
        WHERE codigo_del_producto = '1101035'
    )
    and codigo_del_producto='1101035';
+----------+
| COUNT(*) |
+----------+
|       79 |
+----------+

HAVING

Filtro que se aplica sobre el resultado de una agregación

X Y
A 3
Z 5
Z 1
A 1
E 4
T 3
Z 8
Z 2
T 1
SELECT x, SUM(y) FROM tb
    GROUP BY x
    HAVING SUM(y)>4;
X Y
Z 16
SELECT estado, SUM(limite_de_credito) AS limite_total
    FROM tabla_de_clientes
    GROUP BY estado
    HAVING limite_total>500000;
+--------+--------------+
| estado | limite_total |
+--------+--------------+
| EM     |      1495000 |
+--------+--------------+
SELECT envase, MAX(precio_de_lista) AS precio_mayor,
MIN(precio_de_lista) AS precio_menor
    FROM tabla_de_productos
    GROUP BY envase
    HAVING SUM(precio_de_lista)>80;
+-------------------+--------------+--------------+
| envase            | precio_mayor | precio_menor |
+-------------------+--------------+--------------+
| Botella de Vidrio |        13.31 |          3.3 |
| Botella PET       |        38.01 |            7 |
+-------------------+--------------+--------------+
SELECT envase, MAX(precio_de_lista) AS precio_mayor,
MIN(precio_de_lista) AS precio_menor,
ROUND(SUM(precio_de_lista), 2)
    FROM tabla_de_productos
    GROUP BY envase
    HAVING SUM(precio_de_lista)>80;
+-------------------+--------------+--------------+-------------+
| envase            | precio_mayor | precio_menor | suma_precio |
+-------------------+--------------+--------------+-------------+
| Botella de Vidrio |        13.31 |          3.3 |       85.13 |
| Botella PET       |        38.01 |            7 |      256.64 |
+-------------------+--------------+--------------+-------------+
SELECT envase, MAX(precio_de_lista) AS precio_mayor,
MIN(precio_de_lista) AS precio_menor,
ROUND(SUM(precio_de_lista), 2)
    FROM tabla_de_productos
    GROUP BY envase
    HAVING SUM(precio_de_lista)>=80
        AND precio_mayor >=38;
+-------------+--------------+--------------+-------------+
| envase      | precio_mayor | precio_menor | suma_precio |
+-------------+--------------+--------------+-------------+
| Botella PET |        38.01 |            7 |      256.64 |
+-------------+--------------+--------------+-------------+

¿ Cuales fueron los clientes que hicieron mas de 2000 compras en el 2016 ?

SELECT dni, COUNT(*) FROM facturas
    WHERE YEAR(fecha_venta) = 2016
    GROUP BY dni
    HAVING COUNT(*)>2000;
+-------------+----------+
| dni         | COUNT(*) |
+-------------+----------+
| 3623344710  |     2012 |
| 492472718   |     2008 |
| 50534475787 |     2037 |
+-------------+----------+

CASE

CASE
    WHEN <condicion_1> THEN <valor_1>
    WHEN <condicion_2> THEN <valor_2>
    ...
    WHEN <condicion_n> THEN <valor_n>
    ELSE <valor_por_defecto>

ej. Tabla tb

X Y
Cliente_1 8
Cliente_2 6
Cliente_3 3
Cliente_4 10
Cliente_5 5
Cliente_6 7
Cliente_7 1
Cliente_8 2
Cliente_9 1
CASE
    WHEN y>=8 AND Y<=10 THEN 'Muy bueno'
    WHEN y>=7 AND Y<8 THEN 'Bueno'
    WHEN y>=5 AND Y<7 THEN 'Regular'
    ELSE 'Inferior'
END
FROM tb;

Resultado:

X Y
Cliente_1 Muy bueno
Cliente_2 Regular
Cliente_3 Inferior
Cliente_4 Muy bueno
Cliente_5 Regular
Cliente_6 Bueno
Cliente_7 Inferior
Cliente_8 Inferior
Cliente_9 Inferior
SELECT nombre_del_producto, precio_de_lista,
CASE
    WHEN precio_de_lista >= 12 THEN 'Caro'
    WHEN precio_de_lista >= 5 AND precio_de_lista < 12 THEN 'Asequible'
    ELSE 'Barato'
END as precio
    FROM tabla_de_productos;
+---------------------+-----------------+-----------+
| nombre_del_producto | precio_de_lista | precio    |
+---------------------+-----------------+-----------+
| Sabor da Montaña    |            6.31 | Asequible |
| Línea Citrus        |               7 | Asequible |
| Vida del Campo      |            8.41 | Asequible |
| Vida del Campo      |           19.51 | Caro      |
| Vida del Campo      |           24.01 | Caro      |
| Festival de Sabores |           38.01 | Caro      |
| Clean               |           16.01 | Caro      |
| Light               |            4.56 | Barato    |
| Línea Citrus        |             4.9 | Barato    |
...
SELECT envase, sabor,
CASE
    WHEN precio_de_lista >= 12 THEN 'Caro'
    WHEN precio_de_lista >= 5 AND precio_de_lista < 12 THEN 'Asequible'
    ELSE 'Barato'
END as precio, MIN(precio_de_lista) AS precio_minimo
FROM tabla_de_productos
    WHERE tamano = '700 ml'
        GROUP BY envase,
        CASE
            WHEN precio_de_lista >= 12 THEN 'Caro'
            WHEN precio_de_lista >= 5 AND precio_de_lista < 12 THEN 'Asequible'
            ELSE 'Barato'
        END
        ORDER BY envase;
+-------------------+-------------+-----------+---------------+
| envase            | sabor       | precio    | precio_minimo |
+-------------------+-------------+-----------+---------------+
| Botella de Vidrio | Uva         | Asequible |          6.31 |
| Botella de Vidrio | Lima/Limón  | Barato    |           4.9 |
| Botella de Vidrio | Asaí        | Caro      |         13.31 |
+-------------------+-------------+-----------+---------------+

Registrar el año de nacimiento de los clientes y clasifícar según:

  • Nacidos antes de 1990 = Mayores
  • Nacidos entre 1990 y 1995= Adultos
  • Nacidos después de 1995 = Jovenes

Listar el nombre del cliente y la clasificación

SELECT nombre,
  CASE
    WHEN YEAR(fecha_de_nacimiento) < 1990 THEN 'Mayor'
    WHEN YEAR(fecha_de_nacimiento) >= 1990
        AND YEAR(fecha_de_nacimiento) <= 1995 THEN 'Adulto'
    ELSE 'Joven'
  END AS rango_etario
  FROM tabla_de_clientes;
+--------------------+--------------+
| nombre             | rango_etario |
+--------------------+--------------+
| Erica Carvajo      | Adulto       |
| Marcos Rosas       | Adulto       |
| Jorge Castro       | Adulto       |
| Abel Pintos        | Adulto       |
| Joana Olivera      | Adulto       |
| Paolo Mendez       | Adulto       |
| Gabriel Roca       | Mayor        |
| Marcelo Perez      | Adulto       |
| Luis Silva         | Adulto       |
| Carlos Santivañez  | Mayor        |
| Alberto Rodriguez  | Adulto       |
| Edson Calisaya     | Adulto       |
| María Jimenez      | Adulto       |
| Walter Soruco      | Mayor        |
| Ximena Gómez       | Adulto       |
+--------------------+--------------+

JOIN

Permite unir dos o más tablas a través de un campo en común

Tabla A

Nombre Id
Alejandro 2
Zaida 7
Ximena 8
Elías 10
Tatiana 15
Penélope 9

Tabla B

Id Hobby
4 Lectura
5 Futbol
6 Tenis
7 Alpinismo
8 Fotografía
9 Hípica

INNER JOIN

Devuelve únicamente los registros con llaves correspondientes

SELECT A.nombre, B.hobby FROM tabla_izq A
INNER JOIN
    tabla_der B
    ON A.id = B.id
Nombre Hobby
Zaida Alpinismo
Ximena Fotografía
Penélope Hípica

LEFT JOIN

Maniene todos los registros de la tabla izquierda A y devuelve únicamente los correspondientes con la tabla de la derecha B

SELECT A.nombre, B.hobby FROM tabla_izq A
LEFT JOIN
    tabla_der B
    ON A.id = B.id
Nombre Hobby
Alejandro NULL
Zaida Alpinismo
Ximena Fotografía
Elías NULL
Tatiana NULL
Penélope Hípica

RIGHT JOIN

Maniene todos los registros de la tabla derecha B y devuelve únicamente los correspondientes con la tabla de la izquierda A

SELECT A.nombre, B.hobby FROM tabla_izq A
RIGHT JOIN
    tabla_der B
    ON A.id = B.id
Nombre Hobby
NULL Lectura
NULL Futbol
NULL Tenis
Zaida Alpinismo
Ximena Fotografía
Penélope Hípica

FULL JOIN

Maniene todos los registros de las tablas

SELECT A.nombre, B.hobby FROM tabla_izq A
FULL JOIN
    tabla_der B
    ON A.id = B.id
Nombre Hobby
NULL Lectura
NULL Futbol
NULL Tenis
Zaida Alpinismo
Ximena Fotografía
Penélope Hípica
Alejandro NULL
Elías NULL
Tatiana NULL

CROSS JOIN

Devuelve el prodcuto cartesiano de los registros de las tablas

SELECT A.nombre, B.hobby FROM tabla_izq A, tabla_der B

Devuelve 36 registros con todas las combinaciónes de todos los hobbies y nombres

Nombre Hobby
Alejandro Lectura
Zaida Lectura
Ximena Lectura
Elías Lectura
Tatiana Lectura
Penélope Lectura
Alejandro Futbol
Zaida Futbol
Ximena Futbol
... ...

Prácticas JOIN

Práctica INNER JOIN

SELECT A.nombre, B.matricula, COUNT(*)
FROM tabla_de_vendedores A
INNER JOIN
    facturas B
    ON A.matricula = B.matricula
    GROUP BY A.nombre, B.matricula;
+----------------------+-----------+----------+
| nombre               | matricula | COUNT(*) |
+----------------------+-----------+----------+
| Claudia Morales      | 00236     |    29375 |
| Concepción Martinez  | 00237     |    29113 |
| Miguel Pavón Silva   | 00235     |    29389 |
+----------------------+-----------+----------+

Obtén la facturación anual de la empresa. Ten en cuenta que el valor financiero de las ventas consiste en multiplicar la cantidad por el precio.

Tablas y campos de interes

  • facturas: fecha_venta y numero
  • items_facturas: numero, cantidad y precio
SELECT YEAR(fecha_venta) as Periodo,
ROUND(SUM(cantidad*precio), 3) AS Facturacion
FROM facturas F
    INNER JOIN
        items_facturas IFa
        ON F.numero = IFa.numero
        GROUP BY Periodo
    ORDER BY Periodo DESC;
+---------+--------------+
| Periodo | Facturacion  |
+---------+--------------+
|    2018 | 11022282.826 |
|    2017 | 44359013.133 |
|    2016 | 42362119.436 |
|    2015 | 39848262.063 |
+---------+--------------+

Práctica LEFT y RIGHT JOIN

Clientes con compras con INNER JOIN

SELECT DISTINCT A.dni, A.nombre, B.dni
FROM tabla_de_clientes A
    INNER JOIN
    facturas B
    ON A.dni = B.dni;
+-------------+--------------------+-------------+
| dni         | nombre             | dni         |
+-------------+--------------------+-------------+
| 1471156710  | Erica Carvajo      | 1471156710  |
| 3623344710  | Marcos Rosas       | 3623344710  |
| 492472718   | Jorge Castro       | 492472718   |
| 50534475787 | Abel Pintos        | 50534475787 |
| 5576228758  | Joana Olivera      | 5576228758  |
| 5648641702  | Paolo Mendez       | 5648641702  |
| 5840119709  | Gabriel Roca       | 5840119709  |
| 7771579779  | Marcelo Perez      | 7771579779  |
| 8502682733  | Luis Silva         | 8502682733  |
| 8719655770  | Carlos Santivañez  | 8719655770  |
| 9283760794  | Edson Calisaya     | 9283760794  |
| 94387575700 | María Jimenez      | 94387575700 |
+-------------+--------------------+-------------+

Clientes con compras con LEFT JOIN y condición para encontrar clientes sin compras

SELECT DISTINCT A.dni, A.nombre, B.dni
FROM tabla_de_clientes A
    LEFT JOIN
    facturas B
    ON A.dni = B.dni;
    WHERE B.dni IS NULL;
+-------------+-------------------+------+
| dni         | nombre            | dni  |
+-------------+-------------------+------+
| 9275760794  | Alberto Rodriguez | NULL |
| 94387591700 | Walter Soruco     | NULL |
| 95939180787 | Ximena Gómez      | NULL |
+-------------+-------------------+------+

Clientes con compras con RIGHT JOIN y condición para encontrar clientes sin compras

SELECT DISTINCT A.dni, B.dni, B.nombre
FROM facturas A
    RIGHT JOIN tabla_de_clientes B
    ON A.dni = B.dni
    WHERE A.dni IS NULL;
+------+-------------+-------------------+
| dni  | dni         | nombre            |
+------+-------------+-------------------+
| NULL | 9275760794  | Alberto Rodriguez |
| NULL | 94387591700 | Walter Soruco     |
| NULL | 95939180787 | Ximena Gómez      |
+------+-------------+-------------------+

Práctica CROSS e INNER JOIN

SELECT A.nombre, B.matricula, COUNT(*)
FROM tabla_de_vendedores A, facturas B
    WHERE A.matricula = B.matricula
    GROUP BY A.nombre, B.matricula;
+----------------------+-----------+----------+
| nombre               | matricula | COUNT(*) |
+----------------------+-----------+----------+
| Claudia Morales      | 00236     |    29375 |
| Concepción Martinez  | 00237     |    29113 |
| Miguel Pavón Silva   | 00235     |    29389 |
+----------------------+-----------+----------+
SELECT tabla_de_clientes.nombre AS nombre_cliente,
tabla_de_clientes.barrio as barrio_cliente,
tabla_de_vendedores.nombre as nombre_vendedor,
tabla_de_vendedores.barrio as barrio_vendedor
FROM tabla_de_clientes
    INNER JOIN
    tabla_de_vendedores
    ON tabla_de_clientes.barrio = tabla_de_vendedores.barrio;
+-------------------+----------------+---------------------+-----------------+
| nombre_cliente    | barrio_cliente | nombre_vendedor     | barrio_vendedor |
+-------------------+----------------+---------------------+-----------------+
| Erica Carvajo     | Del Valle      | Claudia Morales     | Del Valle       |
| Marcos Rosas      | Del Valle      | Claudia Morales     | Del Valle       |
| Joana Olivera     | Condesa        | Miguel Pavón Silva  | Condesa         |
| Gabriel Roca      | Del Valle      | Claudia Morales     | Del Valle       |
| Luis Silva        | Contadero      | Concepción Martinez | Contadero       |
| Alberto Rodriguez | Oblatos        | Patricia Sánchez    | Oblatos         |
+-------------------+----------------+---------------------+-----------------+

CROSS JOIN utilizando +0 para representar los BIT

SELECT tabla_de_clientes.nombre, tabla_de_clientes.ciudad, tabla_de_clientes.barrio,
tabla_de_vendedores.nombre, tabla_de_vendedores.vacaciones+0 AS vacaciones
FROM tabla_de_clientes, tabla_de_vendedores
    WHERE tabla_de_clientes.barrio = tabla_de_vendedores.barrio;
+-------------------+------------------+-----------+---------------------+------------+
| nombre            | ciudad           | barrio    | nombre              | vacaciones |
+-------------------+------------------+-----------+---------------------+------------+
| Erica Carvajo     | Ciudad de México | Del Valle | Claudia Morales     |          1 |
| Marcos Rosas      | Ciudad de México | Del Valle | Claudia Morales     |          1 |
| Joana Olivera     | Ciudad de México | Condesa   | Miguel Pavón Silva  |          0 |
| Gabriel Roca      | Ciudad de México | Del Valle | Claudia Morales     |          1 |
| Luis Silva        | Ciudad de México | Contadero | Concepción Martinez |          1 |
| Alberto Rodriguez | Guadalajara      | Oblatos   | Patricia Sánchez    |          0 |
+-------------------+------------------+-----------+---------------------+------------+

UNION

Permite unir dos o más tablas (implícitamente ejecuta DISTINCT)

El número de campos en las tabls de ser iguales (mismos campos y tipos)

ej.

Id Hobby
4 Lectura
5 Futbol
6 Tenis
7 Alpinismo
Id Hobby
8 Fotografía
9 Hípica
5 Futbol
11 Trote

Estructura UNION

<consulta_1>
UNION
<consulta_2>;

Retorna:

Id Hobby
4 Lectura
5 Futbol
6 Tenis
7 Alpinismo
8 Fotografía
9 Hípica
11 Trote

Estructura UNION ALL

<consulta_1>
UNION ALL
<consulta_2>;

Retorna:

Id Hobby
4 Lectura
5 Futbol
6 Tenis
7 Alpinismo
8 Fotografía
9 Hípica
5 Futbol
11 Trote

Práctica UNION

SELECT BARRIO FROM tabla_de_clientes
UNION
SELECT BARRIO FROM tabla_de_vendedores;
+-------------------------+
| BARRIO                  |
+-------------------------+
| Del Valle               |
| Locaxco                 |
| Cuajimalpa              |
| Condesa                 |
| Héroes de Padierna      |
| Carola                  |
| Contadero               |
| Floresta Coyoacán       |
| Oblatos                 |
| Barrio del Niño Jesús   |
| Barragán Hernández      |
| Ex Hacienda Coapa       |
| Alcalde Barranquitas    |
+-------------------------+
SELECT barrio FROM tabla_de_clientes
UNION ALL
SELECT barrio FROM tabla_de_vendedores;
+-------------------------+
| BARRIO                  |
+-------------------------+
| Del Valle               |
| Del Valle               |
| Locaxco                 |
| Cuajimalpa              |
| Condesa                 |
| Héroes de Padierna      |
| Del Valle               |
| Carola                  |
| Contadero               |
| Floresta Coyoacán       |
| Oblatos                 |
| Barrio del Niño Jesús   |
| Barragán Hernández      |
| Ex Hacienda Coapa       |
| Alcalde Barranquitas    |
| Condesa                 |
| Del Valle               |
| Contadero               |
| Oblatos                 |
+-------------------------+
SELECT barrio, nombre, 'Cliente' AS tipo, dni FROM tabla_de_clientes
UNION ALL
SELECT barrio, nombre, 'Vendedor' AS tipo, matricula FROM tabla_de_vendedores;
+-------------------------+----------------------+----------+-------------+
| barrio                  | nombre               | tipo     | dni         |
+-------------------------+----------------------+----------+-------------+
| Del Valle               | Erica Carvajo        | Cliente  | 1471156710  |
| Del Valle               | Marcos Rosas         | Cliente  | 3623344710  |
| Locaxco                 | Jorge Castro         | Cliente  | 492472718   |
| Cuajimalpa              | Abel Pintos          | Cliente  | 50534475787 |
| Condesa                 | Joana Olivera        | Cliente  | 5576228758  |
| Héroes de Padierna      | Paolo Mendez         | Cliente  | 5648641702  |
| Del Valle               | Gabriel Roca         | Cliente  | 5840119709  |
| Carola                  | Marcelo Perez        | Cliente  | 7771579779  |
| Contadero               | Luis Silva           | Cliente  | 8502682733  |
| Floresta Coyoacán       | Carlos Santivañez    | Cliente  | 8719655770  |
| Oblatos                 | Alberto Rodriguez    | Cliente  | 9275760794  |
| Barrio del Niño Jesús   | Edson Calisaya       | Cliente  | 9283760794  |
| Barragán Hernández      | María Jimenez        | Cliente  | 94387575700 |
| Ex Hacienda Coapa       | Walter Soruco        | Cliente  | 94387591700 |
| Alcalde Barranquitas    | Ximena Gómez         | Cliente  | 95939180787 |
| Condesa                 | Miguel Pavón Silva   | Vendedor | 00235       |
| Del Valle               | Claudia Morales      | Vendedor | 00236       |
| Contadero               | Concepción Martinez  | Vendedor | 00237       |
| Oblatos                 | Patricia Sánchez     | Vendedor | 00238       |
+-------------------------+----------------------+----------+-------------+
SELECT tabla_de_clientes.nombre, tabla_de_clientes.ciudad, tabla_de_clientes.barrio,
tabla_de_vendedores.nombre, vacaciones
FROM tabla_de_clientes
    LEFT JOIN
        tabla_de_vendedores
        ON tabla_de_clientes.barrio = tabla_de_vendedores.barrio
UNION
SELECT tabla_de_clientes.nombre, tabla_de_clientes.ciudad, tabla_de_clientes.barrio,
tabla_de_vendedores.nombre, tabla_de_vendedores.vacaciones+0 AS vacaciones
FROM tabla_de_clientes
    RIGHT JOIN
        tabla_de_vendedores
        ON tabla_de_clientes.barrio = tabla_de_vendedores.barrio;
+--------------------+-------------------+-------------------------+----------------------+------------+
| nombre             | ciudad            | barrio                  | nombre               | vacaciones |
+--------------------+-------------------+-------------------------+----------------------+------------+
| Joana Olivera      | Ciudad de México  | Condesa                 | Miguel Pavón Silva   | 0          |
| Erica Carvajo      | Ciudad de México  | Del Valle               | Claudia Morales      | 1          |
| Marcos Rosas       | Ciudad de México  | Del Valle               | Claudia Morales      | 1          |
| Gabriel Roca       | Ciudad de México  | Del Valle               | Claudia Morales      | 1          |
| Luis Silva         | Ciudad de México  | Contadero               | Concepción Martinez  | 1          |
| Alberto Rodriguez  | Guadalajara       | Oblatos                 | Patricia Sánchez     | 0          |
| Jorge Castro       | Ciudad de México  | Locaxco                 | NULL                 | NULL       |
| Abel Pintos        | Ciudad de México  | Cuajimalpa              | NULL                 | NULL       |
| Paolo Mendez       | Ciudad de México  | Héroes de Padierna      | NULL                 | NULL       |
| Marcelo Perez      | Ciudad de México  | Carola                  | NULL                 | NULL       |
| Carlos Santivañez  | Ciudad de México  | Floresta Coyoacán       | NULL                 | NULL       |
| Edson Calisaya     | Ciudad de México  | Barrio del Niño Jesús   | NULL                 | NULL       |
| María Jimenez      | Guadalajara       | Barragán Hernández      | NULL                 | NULL       |
| Walter Soruco      | Ciudad de México  | Ex Hacienda Coapa       | NULL                 | NULL       |
| Ximena Gómez       | Guadalajara       | Alcalde Barranquitas    | NULL                 | NULL       |
+--------------------+-------------------+-------------------------+----------------------+------------+

Subconsultas

Realizar una consulta al interior de otra

X Y
A 3
Z 5
Z 1
A 1
E 4
T 3
Z 8
Z 2
T 1
Y
1
2
SELECT x, y FROM tb1
WHERE y IN (
    SELECT Y FROM tb2
)
X Y
A 3
Z 1
A 1
T 3
Z 2
T 1
SELECT x, SUM(y) AS new_y
FROM tb1 GROUP BY X
X NEW_Y
A 4
E 4
T 4
Z 16
SELECT z.x, z.new_y FROM
    (SELECT x SUM(y) AS new_y
    FROM tb1 GROUP BY x) z
    WHERE z.new_y = 4
X NEW_Y
A 4
E 4
T 4

Práctica Subconsultas

SELECT *, primera_compra+0 FROM tabla_de_clientes
WHERE barrio IN(
    SELECT DISTINCT barrio FROM tabla_de_vendedores
); 
+------------+-------------------+---------------------------------+-----------+-------------------+--------+----------+---------------------+------+------+-------------------+-------------------+------------------+
| DNI        | NOMBRE            | DIRECCION_1                     | BARRIO    | CIUDAD            | ESTADO | CP       | FECHA_DE_NACIMIENTO | EDAD | SEXO | LIMITE_DE_CREDITO | VOLUMEN_DE_COMPRA | primera_compra+0 |
+------------+-------------------+---------------------------------+-----------+-------------------+--------+----------+---------------------+------+------+-------------------+-------------------+------------------+
| 1471156710 | Erica Carvajo     | Heriberto Frías 1107            | Del Valle | Ciudad de México  | EM     | 80012212 | 1990-03-01          |   30 | F    |            170000 |            245000 |                1 |
| 3623344710 | Marcos Rosas      | Av. Universidad                 | Del Valle | Ciudad de México  | EM     | 22002012 | 1995-05-13          |   26 | M    |            110000 |            220000 |                0 |
| 5576228758 | Joana Olivera     | Pachuca 75                      | Condesa   | Ciudad de México  | EM     | 88192029 | 1995-02-14          |   25 | F    |             70000 |            160000 |                0 |
| 5840119709 | Gabriel Roca      | Eje Central Lázaro Cárdenas 911 | Del Valle | Ciudad de México  | EM     | 80010221 | 1985-06-16          |   36 | M    |            140000 |            210000 |                0 |
| 8502682733 | Luis Silva        | Prol. 16 de Septiembre 1156     | Contadero | Ciudad de México  | EM     | 82122020 | 1995-04-07          |   25 | M    |            110000 |            190000 |                1 |
| 9275760794 | Alberto Rodriguez | Circunvalación Oblatos 690      | Oblatos   | Guadalajara       | JC     | 44700000 | 1991-12-28          |   26 | M    |             75000 |             95000 |                1 |
+------------+-------------------+---------------------------------+-----------+-------------------+--------+----------+---------------------+------+------+-------------------+-------------------+------------------+
SELECT x.envase, x.precio_maximo
FROM (
        SELECT envase, MAX(precio_de_lista) AS precio_maximo
        FROM tabla_de_productos
        GROUP BY envase
     ) x
     WHERE x.precio_maximo >=10;
+-------------------+---------------+
| envase            | precio_maximo |
+-------------------+---------------+
| Botella de Vidrio |         13.31 |
| Botella PET       |         38.01 |
+-------------------+---------------+

¿ Como hacer esta query usando subconsultas ?

SELECT DNI, COUNT(*) FROM facturas
WHERE YEAR(FECHA_VENTA) = 2016
GROUP BY DNI
HAVING COUNT(*) > 2000;
+-------------+----------+
| DNI         | COUNT(*) |
+-------------+----------+
| 3623344710  |     2012 |
| 492472718   |     2008 |
| 50534475787 |     2037 |
+-------------+----------+
SELECT X.DNI, X.CONTADOR
FROM (
    SELECT DNI, COUNT(*) AS CONTADOR FROM facturas
    WHERE YEAR(FECHA_VENTA) = 2016
    GROUP BY DNI
    ) X WHERE X.CONTADOR > 2000;

VIEWS

Una View es una tabla lógica que resulta de una consulta que puede ser usada posteriormente en cualquier otra consulta.

La vista tiene un costo de procesamiento, cada vez que es invocada se ejecuta su consulta.

X Y
A 3
Z 5
Z 1
A 1
E 4
T 3
Z 8
Z 2
T 1
CREATE VIEW VW_VIEW AS
SELECT x, SUM(Y) AS new_Y
FROM tb1 GROUP BY x

VW_VIEW

X Y
A 4
E 4
T 4
Z 16

Al almacenar una consulta, se crea una VIEW, en este caso llamada VW_VIEW

tb3

W Y
F 4
H 4
H 5
G 6
F 5
P 16
L 7
M 15
N 6
SELECT VW_VIEW.x, tb3.w FROM VW_VIEW
    INNER JOIN
        tb3 ON VW_VIEW.new_y = tb3.y
        WHERE tb3.y = 16;
X W
Z P

Prácticas VIEW

Creando la vista

CREATE VIEW vw_envases_grandes AS
    SELECT envase, MAX(precio_de_lista) AS precio_maximo
    FROM tabla_de_productos
    GROUP BY envase;

SELECT * FROM vw_envases_grandes;
+-------------------+---------------+
| envase            | precio_maximo |
+-------------------+---------------+
| Botella de Vidrio |         13.31 |
| Botella PET       |         38.01 |
| Lata              |          4.56 |
+-------------------+---------------+

Usando la vista

SELECT x.envase, x.precio_maximo
FROM vw_envases_grandes x
WHERE precio_maximo >=10;
+-------------------+---------------+
| envase            | precio_maximo |
+-------------------+---------------+
| Botella de Vidrio |         13.31 |
| Botella PET       |         38.01 |
+-------------------+---------------+
SELECT a.nombre_del_producto, a.envase, a.precio_de_lista,
b.precio_maximo
FROM tabla_de_productos a
INNER JOIN
    vw_envases_grandes b
    ON a.envase = b.envase;
+---------------------+-------------------+-----------------+---------------+
| nombre_del_producto | envase            | precio_de_lista | precio_maximo |
+---------------------+-------------------+-----------------+---------------+
| Sabor da Montaña    | Botella de Vidrio |            6.31 |         13.31 |
| Línea Citrus        | Botella PET       |               7 |         38.01 |
| Vida del Campo      | Botella de Vidrio |            8.41 |         13.31 |
| Vida del Campo      | Botella PET       |           19.51 |         38.01 |
| Vida del Campo      | Botella PET       |           24.01 |         38.01 |
| Festival de Sabores | Botella PET       |           38.01 |         38.01 |
| Clean               | Botella PET       |           16.01 |         38.01 |
...
SELECT a.nombre_del_producto, a.envase,
((a.precio_de_lista/b.precio_maximo)-1)*100 AS variacion_percent
FROM tabla_de_productos a
INNER JOIN
    vw_envases_grandes b
    ON a.envase = b.envase;
+---------------------+-------------------+---------------------+
| nombre_del_producto | envase            | variacion_percent   |
+---------------------+-------------------+---------------------+
| Sabor da Montaña    | Botella de Vidrio |  -52.59203798761971 |
| Línea Citrus        | Botella PET       |  -81.58379292525673 |
| Vida del Campo      | Botella de Vidrio |  -36.81442838260782 |
...

FUNCIONES

  • MySQL Functions & Operators Doc
  • MySQL Functions en W3Schools
  • MariaDB Functions List
  • MariaDB Functions & Operators Doc
  • Diferencias entre funciones MySQL y MariaDB

LTRIM

SELECT LTRIM("    TRIM IZQUIERDO     ") AS LTRIM;
SELECT RTRIM("    TRIM DERECHO     ") AS RTRIM;
SELECT TRIM("    TRIM GENERAL     ") AS TRIM;
+---------------------+
| LTRIM               |
+---------------------+
| TRIM IZQUIERDO      |
+---------------------+

+------------------+
| RTRIM            |
+------------------+
|     TRIM DERECHO |
+------------------+

+--------------+
| TRIM         |
+--------------+
| TRIM GENERAL |
+--------------+

CONCAT

SELECT CONCAT("MySQL es entretenido,", " no lo crees?") AS CONCAT;
+------------------------------------+
| CONCAT                             |
+------------------------------------+
| MySQL es entretenido, no lo crees? |
+------------------------------------+

UPPER, LOWER

SELECT UPPER("MySQL es entretenido") AS UPPER;
SELECT LOWER("MYSQL ES ENTRETENIDO") AS LOWER;
+----------------------+
| UPPER                |
+----------------------+
| MYSQL ES ENTRETENIDO |
+----------------------+

+----------------------+
| LOWER                |
+----------------------+
| mysql es entretenido |
+----------------------+

SUBSTRING

SELECT SUBSTRING("MySQL es entretenido e interesante, bastante que aprender", 24, 11)
    AS SUBSTRING;
+-------------+
| SUBSTRING   |
+-------------+
| interesante |
+-------------+

Práctica funciones

SELECT CONCAT(nombre, " ", dni) AS nombre_dni
FROM tabla_de_clientes;
+-------------------------------+
| nombre_dni                    |
+-------------------------------+
| Erica Carvajo 1471156710      |
| Marcos Rosas 3623344710       |
| Jorge Castro 492472718        |
| Abel Pintos 50534475787       |
| Joana Olivera 5576228758      |
...

Crear una consulta listando nombre y dirección de cliente, con el detalle de calle, barrio, ciudad y estado

SELECT nombre, CONCAT(direccion_1, " ", barrio, " ", ciudad, " ", estado)
AS direccion
FROM tabla_de_clientes;
+---------------+--------------------------------------------------------+
| nombre        | direccion                                              |
+---------------+--------------------------------------------------------+
| Erica Carvajo | Heriberto Frías 1107 Del Valle Ciudad de México EM     |
| Marcos Rosas  | Av. Universidad Del Valle Ciudad de México EM          |
| Jorge Castro  | Federal México-Toluca 5690 Locaxco Ciudad de México EM |
...

DATE FUNCTIONS

ADDDATE, CURDATE

SELECT ADDDATE(CURDATE(), INTERVAL 5 YEAR);
+-------------------------------------+
| ADDDATE(CURDATE(), INTERVAL 5 YEAR) |
+-------------------------------------+
| 2028-10-16                          |
+-------------------------------------+

CURRENT_TIMESTAMP

SELECT CURRENT_TIMESTAMP();
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2023-10-16 14:47:58 |
+---------------------+

DATE DATEDIFF

SELECT DATE("2023-10-16");
SELECT DATEDIFF("2025-12-02", CURDATE());
+--------------------+
| DATE("2023-10-16") |
+--------------------+
| 2023-10-16         |
+--------------------+

+-----------------------------------+
| DATEDIFF("2025-12-02", CURDATE()) |
+-----------------------------------+
|                               778 |
+-----------------------------------+

DATES NAMES

SELECT MONTHNAME(CURDATE()), DAYNAME(CURDATE()), TIME_TO_SEC(CURRENT_TIME());
+----------------------+--------------------+-----------------------------+
| MONTHNAME(CURDATE()) | DAYNAME(CURDATE()) | TIME_TO_SEC(CURRENT_TIME()) |
+----------------------+--------------------+-----------------------------+
| October              | Monday             |                       53946 |
+----------------------+--------------------+-----------------------------+
SELECT CONCAT("Fecha y hora actual: ",
DATE_FORMAT(CURRENT_TIMESTAMP(), "%W, %d/%m/%Y, %T")) AS FECHA;
+---------------------------------------------------+
| FECHA                                             |
+---------------------------------------------------+
| Fecha y hora actual: Monday, 16/10/2023, 15:49:02 |
+---------------------------------------------------+

Práctica DATE FUNCTIONS

SELECT DISTINCT fecha_venta,
DAYNAME(fecha_venta) AS DIA,
MONTHNAME(fecha_venta) AS MES,
YEAR(fecha_venta) AS AÑO
FROM facturas;
+-------------+-----------+---------+------+
| fecha_venta | DIA       | MES     | AÑO  |
+-------------+-----------+---------+------+
| 2015-01-01  | Thursday  | January | 2015 |
| 2015-01-02  | Friday    | January | 2015 |
| 2015-01-03  | Saturday  | January | 2015 |
...

Crear una consulta que muestre el nombre y la edad actual del cliente

SELECT nombre, TIMESTAMPDIFF(YEAR, fecha_de_nacimiento, CURDATE()) AS edad
FROM tabla_de_clientes;
+--------------------+------+
| nombre             | edad |
+--------------------+------+
| Erica Carvajo      |   33 |
| Marcos Rosas       |   28 |
| Jorge Castro       |   28 |
...

Funciones Matemáticas

CEIL, FLOOR, ROUND

SELECT CEIL(25.01), FLOOR(25.99), ROUND(25.5), ROUND(25.456789, 2);
+-------------+--------------+-------------+---------------------+
| CEIL(25.01) | FLOOR(25.99) | ROUND(25.5) | ROUND(25.456789, 2) |
+-------------+--------------+-------------+---------------------+
|          26 |           25 |          26 |               25.46 |
+-------------+--------------+-------------+---------------------+

Calcular el valor del impuesto pago en el año de 2016 redondeando al menor entero. Considerar:

  • tabla de facturas -> impuesto
  • tabla items_facturas -> cantidad y facturación
SELECT YEAR(fecha_venta) AS AÑO,
FLOOR(SUM(impuesto * (cantidad * precio))) AS TOTAL_IMPUESTOS
FROM facturas F
    INNER JOIN items_facturas IFa ON F.numero = IFa.numero
    WHERE YEAR(fecha_venta) = 2016
    GROUP BY AÑO;
+------+-----------------+
| AÑO  | TOTAL_IMPUESTOS |
+------+-----------------+
| 2016 |         4656937 |
+------+-----------------+

CONVERT

SELECT SUBSTRING(CONVERT(23.45, CHAR),3,1) AS RESULTADO;
+-----------+
| RESULTADO |
+-----------+
| .         |
+-----------+

Crear consulta que retorne el sgte. resultado por cliente

El cliente <nombre> compró <cantidad> en el año 2016

SELECT CONCAT('El cliente ', TC.NOMBRE, ' compró $', 
CONVERT(SUM(IFa.CANTIDAD * IFa.precio), CHAR(20))
 , '.- el año ', CONVERT(YEAR(F.FECHA_VENTA), CHAR(20))) AS FRASE
FROM facturas F
    INNER JOIN items_facturas IFa ON F.NUMERO = IFa.NUMERO
        INNER JOIN tabla_de_clientes TC ON F.DNI = TC.DNI
        WHERE YEAR(FECHA_VENTA) = 2016
    GROUP BY TC.NOMBRE, YEAR(FECHA_VENTA);
+--------------------------------------------------------------------------+
| FRASE                                                                    |
+--------------------------------------------------------------------------+
| El cliente Abel Pintos compró $3111017.9194583893.- el año 2016          |
| El cliente Carlos Santivañez compró $2827179.4774594307.- el año 2016    |
| El cliente Edson Calisaya compró $3076894.2775964737.- el año 2016       |
...

Informes

Compras por cliente, detalle DNI, MES-AÑO y COMPRAS

SELECT F.dni,
       DATE_FORMAT(F.fecha_venta, "%m-%Y") AS mes_año,
       I.cantidad
FROM facturas F
    INNER JOIN
        items_facturas I
    ON F.numero = I.numero
    ORDER BY cantidad;
+-------------+----------+----------+
| dni         | mes_año  | cantidad |
+-------------+----------+----------+
| 7771579779  | 01-2015  |       63 |
| 7771579779  | 01-2015  |       26 |
| 7771579779  | 01-2015  |       67 |
...

Compras mensuales por cliente

SELECT F.dni,
       DATE_FORMAT(F.fecha_venta, "%m-%Y") AS mes_año,
       SUM(I.cantidad) AS VENTAS
FROM facturas F
    INNER JOIN
        items_facturas I
    ON F.numero = I.numero
    GROUP BY F.dni mes_año
    ORDER BY mes_año;
+-------------+----------+--------+
| dni         | mes_año  | VENTAS |
+-------------+----------+--------+
| 50534475787 | 01-2015  |  23176 |
| 1471156710  | 01-2015  |  24316 |
| 5576228758  | 01-2015  |  21563 |
...

Listar clientes con ventas inválidas y calcular diferencia entre el límite de venta máximo y la cantidad vendida en porcentaje.

SELECT
    A.DNI, A.NOMBRE, A.MES_AÑO,
    A.CANTIDAD_VENDIDA - A.CANTIDAD_MAXIMA AS DIFERENCIA,
CASE
   WHEN  (A.CANTIDAD_VENDIDA - A.CANTIDAD_MAXIMA) <= 0 THEN 'Venta Válida'
   ELSE 'Venta Inválida'
END
    AS STATUS_VENTA,
    ROUND((1 - (A.CANTIDAD_MAXIMA/A.CANTIDAD_VENDIDA)) * 100,2) AS PORCENTAJE
    FROM(
        SELECT F.DNI,
        TC.NOMBRE,
        DATE_FORMAT(F.FECHA_VENTA, "%m - %Y") AS MES_AÑO, 
        SUM(IFa.CANTIDAD) AS CANTIDAD_VENDIDA, 
        MAX(VOLUMEN_DE_COMPRA)/10 AS CANTIDAD_MAXIMA  
        FROM facturas F 
            INNER JOIN 
                items_facturas IFa
            ON F.NUMERO = IFa.NUMERO
            INNER JOIN 
                tabla_de_clientes TC
            ON TC.DNI = F.DNI
    GROUP BY
    F.DNI, TC.NOMBRE, DATE_FORMAT(F.FECHA_VENTA, "%m - %Y"))A
    WHERE (A.CANTIDAD_MAXIMA - A.CANTIDAD_VENDIDA) < 0;
+-------------+--------------------+-----------+------------+-----------------+------------+
| DNI         | NOMBRE             | MES_AÑO   | DIFERENCIA | STATUS_VENTA    | PORCENTAJE |
+-------------+--------------------+-----------+------------+-----------------+------------+
| 1471156710  | Erica Carvajo      | 05 - 2015 |       1885 | Venta Inválida  |       7.14 |
| 1471156710  | Erica Carvajo      | 06 - 2016 |        542 | Venta Inválida  |       2.16 |
| 1471156710  | Erica Carvajo      | 07 - 2017 |       1715 | Venta Inválida  |       6.54 |
| 1471156710  | Erica Carvajo      | 08 - 2015 |        426 | Venta Inválida  |       1.71 |
| 3623344710  | Marcos Rosas       | 01 - 2016 |       2876 | Venta Inválida  |      11.56 |
...

Listar solo clientes con ventas inválidas en el año 2018 excediendo más del 50% de su límite permitido por mes. Calcular el porcentaje de diferencia entre el límite de venta máximo y la cantidad vendida.

SELECT A.DNI, A.NOMBRE, A.MES_AÑO, 
A.CANTIDAD_VENDIDA - A.CANTIDAD_MAXIMA AS DIFERENCIA,
CASE
    WHEN  (A.CANTIDAD_VENDIDA - A.CANTIDAD_MAXIMA) <= 0 THEN 'Venta Válida'
    ELSE 'Venta Inválida'
END AS
    STATUS_VENTA,
    ROUND((1 - (A.CANTIDAD_MAXIMA/A.CANTIDAD_VENDIDA)) * 100,2) AS PORCENTAJE
    FROM(
        SELECT F.DNI,
        TC.NOMBRE,
        DATE_FORMAT(F.FECHA_VENTA, "%m - %Y") AS MES_AÑO, 
        SUM(IFa.CANTIDAD) AS CANTIDAD_VENDIDA, 
        MAX(VOLUMEN_DE_COMPRA)/10 AS CANTIDAD_MAXIMA  
        FROM facturas F 
        INNER JOIN 
            items_facturas IFa
        ON F.NUMERO = IFa.NUMERO
        INNER JOIN 
            tabla_de_clientes TC
        ON TC.DNI = F.DNI
    GROUP BY
        F.DNI, TC.NOMBRE, DATE_FORMAT(F.FECHA_VENTA, "%m - %Y")) A
    WHERE (A.CANTIDAD_MAXIMA - A.CANTIDAD_VENDIDA) < 0
        AND ROUND((1 - (A.CANTIDAD_MAXIMA/A.CANTIDAD_VENDIDA)) * 100,2) > 50
        AND A.MES_AÑO LIKE "%2018";
+-----------+--------------+-----------+------------+-----------------+------------+
| DNI       | NOMBRE       | MES_AÑO   | DIFERENCIA | STATUS_VENTA    | PORCENTAJE |
+-----------+--------------+-----------+------------+-----------------+------------+
| 492472718 | Jorge Castro | 02 - 2018 |      11219 | Venta Inválida  |      54.15 |
| 492472718 | Jorge Castro | 03 - 2018 |      10789 | Venta Inválida  |      53.18 |
+-----------+--------------+-----------+------------+-----------------+------------+

Informe de ventas por sabor en el 2016

SELECT P.SABOR, SUM(I.CANTIDAD) AS TOTAL, YEAR(F.FECHA_VENTA) AS AÑO
FROM tabla_de_productos P
INNER JOIN items_facturas I
ON P.codigo_del_producto = I.codigo_del_producto
INNER JOIN facturas F
ON F.NUMERO = I.NUMERO
WHERE YEAR(F.FECHA_VENTA) = 2016
GROUP BY P.SABOR, YEAR(F.FECHA_VENTA)
ORDER BY SUM(I.CANTIDAD) DESC;
+-----------------+--------+------+
| SABOR           | TOTAL  | AÑO  |
+-----------------+--------+------+
| Mango           | 613309 | 2016 |
| Sandía          | 487625 | 2016 |
| Naranja         | 483663 | 2016 |
| Manzana         | 363166 | 2016 |
| Maracuyá        | 245456 | 2016 |
| Lima/Limón      | 239634 | 2016 |
| Frutilla/Limón  | 238118 | 2016 |
| Cereza/Manzana  | 236535 | 2016 |
| Asaí            | 235660 | 2016 |
| Asái            | 121615 | 2016 |
| Uva             | 120597 | 2016 |
| Cereza          | 120478 | 2016 |
| Frutilla        | 120384 | 2016 |
+-----------------+--------+------+
SELECT VENTAS_SABOR.SABOR,
    VENTAS_SABOR.AÑO,
    VENTAS_SABOR.CANTIDAD_TOTAL,
    ROUND((VENTAS_SABOR.CANTIDAD_TOTAL/VENTA_TOTAL.CANTIDAD_TOTAL)*100,2) 
    AS PORCENTAJE
FROM (
    SELECT P.SABOR,
        SUM(IFa.CANTIDAD) AS CANTIDAD_TOTAL, 
        YEAR(F.FECHA_VENTA) AS AÑO
    FROM tabla_de_productos P
    INNER JOIN items_facturas IFa
    ON P.CODIGO_DEL_PRODUCTO = IFa.CODIGO_DEL_PRODUCTO
        INNER JOIN facturas F
        ON F.NUMERO = IFa.NUMERO
    WHERE YEAR(F.FECHA_VENTA) = 2016
    GROUP BY P.SABOR, YEAR(F.FECHA_VENTA)
    ORDER BY SUM(IFa.CANTIDAD) DESC
) VENTAS_SABOR
    INNER JOIN (
        SELECT SUM(IFa.CANTIDAD) AS CANTIDAD_TOTAL, 
        YEAR(F.FECHA_VENTA) AS AÑO
        FROM tabla_de_productos P
            INNER JOIN items_facturas IFa
            ON P.CODIGO_DEL_PRODUCTO = IFa.CODIGO_DEL_PRODUCTO
                INNER JOIN facturas F
                ON F.NUMERO = IFa.NUMERO
        WHERE YEAR(F.FECHA_VENTA) = 2016
        GROUP BY YEAR(F.FECHA_VENTA)
    ) VENTA_TOTAL
ON VENTA_TOTAL.AÑO = VENTAS_SABOR.AÑO
ORDER BY VENTAS_SABOR.CANTIDAD_TOTAL DESC;
+-----------------+------+----------------+------------+
| SABOR           | AÑO  | CANTIDAD_TOTAL | PORCENTAJE |
+-----------------+------+----------------+------------+
| Mango           | 2016 |         613309 |      16.91 |
| Sandía          | 2016 |         487625 |      13.45 |
| Naranja         | 2016 |         483663 |      13.34 |
| Manzana         | 2016 |         363166 |      10.01 |
| Maracuyá        | 2016 |         245456 |       6.77 |
| Lima/Limón      | 2016 |         239634 |       6.61 |
| Frutilla/Limón  | 2016 |         238118 |       6.57 |
| Cereza/Manzana  | 2016 |         236535 |       6.52 |
| Asaí            | 2016 |         235660 |       6.50 |
| Asái            | 2016 |         121615 |       3.35 |
| Uva             | 2016 |         120597 |       3.33 |
| Cereza          | 2016 |         120478 |       3.32 |
| Frutilla        | 2016 |         120384 |       3.32 |
+-----------------+------+----------------+------------+

El mismo ranking pero por tamaño

SELECT 
    VENTAS_TAMANO.TAMANO,
    VENTAS_TAMANO.AÑO,
    VENTAS_TAMANO.CANTIDAD_TOTAL,
    ROUND((VENTAS_TAMANO.CANTIDAD_TOTAL/VENTA_TOTAL.CANTIDAD_TOTAL)*100,2) 
    AS PORCENTAJE
FROM (
    SELECT P.TAMANO,
    SUM(IFa.CANTIDAD) AS CANTIDAD_TOTAL, 
    YEAR(F.FECHA_VENTA) AS AÑO
    FROM tabla_de_productos P
    INNER JOIN items_facturas IFa
        ON P.CODIGO_DEL_PRODUCTO = IFa.CODIGO_DEL_PRODUCTO
        INNER JOIN facturas F
            ON F.NUMERO = IFa.NUMERO
    WHERE YEAR(F.FECHA_VENTA) = 2016
    GROUP BY P.TAMANO, YEAR(F.FECHA_VENTA)
    ORDER BY SUM(IFa.CANTIDAD) DESC
) VENTAS_TAMANO
    INNER JOIN (
        SELECT
        SUM(IFa.CANTIDAD) AS CANTIDAD_TOTAL, 
        YEAR(F.FECHA_VENTA) AS AÑO
        FROM tabla_de_productos P
            INNER JOIN items_facturas IFa
            ON P.CODIGO_DEL_PRODUCTO = IFa.CODIGO_DEL_PRODUCTO
                INNER JOIN facturas F
                ON F.NUMERO = IFa.NUMERO
        WHERE YEAR(F.FECHA_VENTA) = 2016
        GROUP BY YEAR(F.FECHA_VENTA)
    ) VENTA_TOTAL
    ON VENTA_TOTAL.AÑO = VENTAS_TAMANO.AÑO
ORDER BY VENTAS_TAMANO.CANTIDAD_TOTAL DESC;
+------------+------+----------------+------------+
| TAMANO     | AÑO  | CANTIDAD_TOTAL | PORCENTAJE |
+------------+------+----------------+------------+
| 700 ml     | 2016 |        1072577 |      29.58 |
| 1,5 Litros | 2016 |         728225 |      20.08 |
| 350 ml     | 2016 |         615021 |      16.96 |
| 1 Litro    | 2016 |         605779 |      16.71 |
| 2 Litros   | 2016 |         360030 |       9.93 |
| 470 ml     | 2016 |         244608 |       6.75 |
+------------+------+----------------+------------+