Repository: mouredev/hello-sql Branch: main Commit: d3cd3a0f1205 Files: 41 Total size: 47.7 KB Directory structure: gitextract_icj39eh6/ ├── 01_Reading/ │ ├── 00_comments.sql │ ├── 01_select.sql │ ├── 02_distinct.sql │ ├── 03_where.sql │ ├── 04_order_by.sql │ ├── 05_like.sql │ ├── 06_and_or_not.sql │ ├── 07_limit.sql │ ├── 08_null.sql │ ├── 09_min_max.sql │ ├── 10_count.sql │ ├── 11_sum.sql │ ├── 12_avg.sql │ ├── 13_in.sql │ ├── 14_between.sql │ ├── 15_alias.sql │ ├── 16_concat.sql │ ├── 17_group_by.sql │ ├── 18_having.sql │ └── 19_case.sql ├── 02_Writing/ │ ├── 01_insert.sql │ ├── 02_update.sql │ └── 03_delete.sql ├── 03_Database/ │ ├── 01_create_database.sql │ └── 02_drop_database.sql ├── 04_Tables/ │ ├── 01_create_table.sql │ ├── 02_drop_table.sql │ ├── 03_alter_table.sql │ └── 04_relationships.sql ├── 05_Join/ │ ├── 01_inner_join.sql │ ├── 02_left_join.sql │ ├── 03_right_join.sql │ └── 04_union.sql ├── 06_Advanced/ │ ├── 01_index.sql │ ├── 02_triggers.sql │ ├── 03_views.sql │ ├── 04_stored_procedures.sql │ ├── 05_transactions.sql │ └── 06_connectors.py ├── LICENSE └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: 01_Reading/00_comments.sql ================================================ /* COMENTAROS Lección 10.1: https://youtu.be/OuJerKzV5T0?t=7512 */ -- Comentario en una lína /* Este es un comentario en varias líneas */ ================================================ FILE: 01_Reading/01_select.sql ================================================ /* SELECT Lección 8: https://youtu.be/OuJerKzV5T0?t=5618 */ -- Obtiene todos los datos de la tabla "users" SELECT * FROM users; -- Obtiene todos los nombres de la tabla "users" SELECT name FROM users; -- Obtiene todos los identificadores y nombres de la tabla "users" SELECT user_id, name FROM users; ================================================ FILE: 01_Reading/02_distinct.sql ================================================ /* DISTINCT Lección 9.1: https://youtu.be/OuJerKzV5T0?t=6089 */ -- Obtiene todos los datos distintos entre sí de la tabla "users" SELECT DISTINCT * FROM users; -- Obtiene todos los valores distintos referentes al atributo edad de la tabla "users" SELECT DISTINCT age FROM users; ================================================ FILE: 01_Reading/03_where.sql ================================================ /* WHERE Lección 9.2: https://youtu.be/OuJerKzV5T0?t=6384 */ -- Filtra todos los datos de la tabla "users" con edad igual a 15 SELECT * FROM users WHERE age = 15; -- Filtra todos los nombres de la tabla "users" con edad igual a 15 SELECT name FROM users WHERE age = 15; -- Filtra todos los nombres distintos de la tabla "users" con edad igual a 15 SELECT DISTINCT name FROM users WHERE age = 15; -- Filtra todas las edades distintas de la tabla "users" con edad igual a 15 SELECT DISTINCT age FROM users WHERE age = 15; ================================================ FILE: 01_Reading/04_order_by.sql ================================================ /* ORDER BY Lección 9.3: https://youtu.be/OuJerKzV5T0?t=6592 */ -- Ordena todos los datos de la tabla "users" por edad (ascendente por defecto) SELECT * FROM users ORDER BY age; -- Ordena todos los datos de la tabla "users" por edad de manera ascendente SELECT * FROM users ORDER BY age ASC; -- Ordena todos los datos de la tabla "users" por edad de manera descendente SELECT * FROM users ORDER BY age DESC; -- Obtiene todos los datos de la tabla "users" con email igual a sara@gmail.com y los ordena por edad de manera descendente SELECT * FROM users WHERE email='sara@gmail.com' ORDER BY age DESC; -- Obtiene todos los nombres de la tabla "users" con email igual a sara@gmail.com y los ordena por edad de manera descendente SELECT name FROM users WHERE email='sara@gmail.com' ORDER BY age DESC; ================================================ FILE: 01_Reading/05_like.sql ================================================ /* LIKE Lección 9.4: https://youtu.be/OuJerKzV5T0?t=6894 */ -- Obtiene todos datos de la tabla "users" que contienen un email con el texto "gmail.com" en su parte final SELECT * FROM users WHERE email LIKE '%gmail.com'; -- Obtiene todos datos de la tabla "users" que contienen un email con el texto "sara" en su parte inicial SELECT * FROM users WHERE email LIKE 'sara%'; -- Obtiene todos datos de la tabla "users" que contienen un email una arroba SELECT * FROM users WHERE email LIKE '%@%'; ================================================ FILE: 01_Reading/06_and_or_not.sql ================================================ /* NOT, AND, OR Lección 9.5: https://youtu.be/OuJerKzV5T0?t=7194 */ -- Obtiene todos datos de la tabla "users" con email distinto a sara@gmail.com SELECT * FROM users WHERE NOT email = 'sara@gmail.com'; -- Obtiene todos datos de la tabla "users" con email distinto a sara@gmail.com y edad igual a 15 SELECT * FROM users WHERE NOT email = 'sara@gmail.com' AND age = 15; -- Obtiene todos datos de la tabla "users" con email distinto a sara@gmail.com o edad igual a 15 SELECT * FROM users WHERE NOT email = 'sara@gmail.com' OR age = 15; ================================================ FILE: 01_Reading/07_limit.sql ================================================ /* LIMIT Lección 9.6: https://youtu.be/OuJerKzV5T0?t=7395 */ -- Obtiene las 3 primeras filas de la tabla "users" SELECT * FROM users LIMIT 3; -- Obtiene las 2 primeras filas de la tabla "users" con email distinto a sara@gmail.com o edad igual a 15 SELECT * FROM users WHERE NOT email = 'sara@gmail.com' OR age = 15 LIMIT 2; ================================================ FILE: 01_Reading/08_null.sql ================================================ /* NULL Lección 10.2: https://youtu.be/OuJerKzV5T0?t=7615 */ -- Obtiene todos datos de la tabla "users" de la tabla "users" con email nulo SELECT * FROM users WHERE email IS NULL; -- Obtiene todos datos de la tabla "users" de la tabla "users" con email no nulo SELECT * FROM users WHERE email IS NOT NULL; -- Obtiene todos datos de la tabla "users" de la tabla "users" con email no nulo y edad igual a 15 SELECT * FROM users WHERE email IS NOT NULL AND age = 15; /* IFNULL Lección 10.14: https://youtu.be/OuJerKzV5T0?t=10023 */ -- Obtiene el nombre, apellido y edad de la tabla "users", y si la edad es nula la muestra como 0 SELECT name, surname, IFNULL(age, 0) AS age FROM users; ================================================ FILE: 01_Reading/09_min_max.sql ================================================ /* MIN, MAX Lección 10.3: https://youtu.be/OuJerKzV5T0?t=7834 */ -- Obtiene el valor menor del campo edad de la tabla "users" Select MIN(age) FROM users; -- Obtiene el valor mayor del campo edad de la tabla "users" Select MAX(age) FROM users; ================================================ FILE: 01_Reading/10_count.sql ================================================ /* COUNT Lección 10.4: https://youtu.be/OuJerKzV5T0?t=8043 */ -- Cuenta cuantas filas contiene la tabla "users" Select COUNT(*) FROM users; -- Cuenta cuantas filas contienen un dato no nulo en el campo edad de la tabla "users" Select COUNT(age) FROM users; ================================================ FILE: 01_Reading/11_sum.sql ================================================ /* SUM Lección 10.5: https://youtu.be/OuJerKzV5T0?t=8128 */ -- Suma todos los valores del campo edad de la tabla "users" Select SUM(age) FROM users; ================================================ FILE: 01_Reading/12_avg.sql ================================================ /* AVG Lección 10.6: https://youtu.be/OuJerKzV5T0?t=8293 */ -- Obitne la media de edad de la tabla "users" Select AVG(age) FROM users; ================================================ FILE: 01_Reading/13_in.sql ================================================ /* IN Lección 10.7: https://youtu.be/OuJerKzV5T0?t=8335 */ -- Ordena todos los datos de la tabla "users" con nombre igual a brais y sara SELECT * FROM users WHERE name IN ('brais', 'sara') ================================================ FILE: 01_Reading/14_between.sql ================================================ /* BETWEEN Lección 10.8: https://youtu.be/OuJerKzV5T0?t=8559 */ -- Ordena todos los datos de la tabla "users" con edad comprendida entre 20 y 30 SELECT * FROM users WHERE age BETWEEN 20 AND 30 ================================================ FILE: 01_Reading/15_alias.sql ================================================ /* ALIAS Lección 10.9: https://youtu.be/OuJerKzV5T0?t=8667 */ -- Establece el alias 'Fecha de inicio en programación' a la columna init_date SELECT name, init_date AS 'Fecha de inicio en programación' FROM users WHERE name = 'Brais' -- Consulta igual que la anterior. Representa la posibilidad de usar comillas dobles para cadenas SELECT name, init_date AS "Fecha de inicio en programación" FROM users WHERE name = "Brais" ================================================ FILE: 01_Reading/16_concat.sql ================================================ /* CONCAT Lección 10.10: https://youtu.be/OuJerKzV5T0?t=8826 */ -- Concatena en una sola columa los campos nombre y apellido SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) FROM users -- Concatena en una sola columa los campos nombre y apellido y le establece el alias 'Nombre completo' SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) AS 'Nombre completo' FROM users ================================================ FILE: 01_Reading/17_group_by.sql ================================================ /* GROUP BY Lección 10.11: https://youtu.be/OuJerKzV5T0?t=8960 */ -- Agrupa los resultados por edad diferente SELECT MAX(age) FROM users GROUP BY age -- Agrupa los resultados por edad diferente y cuenta cuantos registros existen de cada una SELECT COUNT(age), age FROM users GROUP BY age -- Agrupa los resultados por edad diferente, cuenta cuantos registros existen de cada una y los ordena SELECT COUNT(age), age FROM users GROUP BY age ORDER BY age ASC -- Agrupa los resultados por edad diferente mayor de 15, cuenta cuantos registros existen de cada una y los ordena SELECT COUNT(age), age FROM users WHERE age > 15 GROUP BY age ORDER BY age ASC ================================================ FILE: 01_Reading/18_having.sql ================================================ /* HAVING Lección 10.12: https://youtu.be/OuJerKzV5T0?t=9265 */ -- Cuenta cuantas filas contienen un dato no nulo en el campo edad de la tabla "users" mayor que 3 SELECT COUNT(age) FROM users HAVING COUNT(age) > 3 ================================================ FILE: 01_Reading/19_case.sql ================================================ /* CASE Lección 10.13: https://youtu.be/OuJerKzV5T0?t=9486 */ -- Obtiene todos los datos de la tabla "users" y establece condiciones de visualización de cadenas de texto según el valor de la edad SELECT *, CASE WHEN age > 18 THEN 'Es mayor de edad' WHEN age = 18 THEN 'Acaba de cumplir la mayoría de edad' ELSE 'Es menor de edad' END AS '¿Es mayor de edad?' FROM users; -- Obtiene todos los datos de la tabla "users" y establece condiciones de visualización de valores booleanos según el valor de la edad SELECT *, CASE WHEN age > 17 THEN True ELSE False END AS '¿Es mayor de edad?' FROM users; ================================================ FILE: 02_Writing/01_insert.sql ================================================ /* INSERT Lección 11.1: https://youtu.be/OuJerKzV5T0?t=10370 */ -- Inserta un registro con identificador, nombre y apellido en la tabla "users" INSERT INTO users (user_id, name, surname) VALUES (8, 'María', 'López') -- Inserta un registro con nombre y apellido en la tabla "users" INSERT INTO users (name, surname) VALUES ('Paco', 'Pérez') -- Inserta un registro con identificador no correlativo, nombre y apellido en la tabla "users" INSERT INTO users (user_id, name, surname) VALUES (11, 'El', 'Merma') ================================================ FILE: 02_Writing/02_update.sql ================================================ /* UPDATE Lección 11.2: https://youtu.be/OuJerKzV5T0?t=10621 */ -- Estable el valor 21 para la edad del registro de la tabla "users" con identificador igual a 11 UPDATE users SET age = '21' WHERE user_id = 11 -- Estable el valor 20 para la edad del registro de la tabla "users" con identificador igual a 11 UPDATE users SET age = '20' WHERE user_id = 11 -- Estable edad y una fecha para registro de la tabla "users" con identificador igual a 11 UPDATE users SET age = 20, init_date = '2020-10-12' WHERE user_id = 11 ================================================ FILE: 02_Writing/03_delete.sql ================================================ /* DELETE Lección 11.3: https://youtu.be/OuJerKzV5T0?t=10920 */ -- Elimina el registro de la tabla "users" con identificador igual a 11 DELETE FROM users WHERE user_id = 11; ================================================ FILE: 03_Database/01_create_database.sql ================================================ /* CREATE DATABASE Lección 12.1: https://youtu.be/OuJerKzV5T0?t=11064 */ -- Crea una base de datos llamada "test" CREATE DATABASE test; ================================================ FILE: 03_Database/02_drop_database.sql ================================================ /* DROP DATABASE Lección 12.2: https://youtu.be/OuJerKzV5T0?t=11180 */ -- Elimina la base de datos llamada "test" DROP DATABASE test; ================================================ FILE: 04_Tables/01_create_table.sql ================================================ /* CREATE TABLE Lección 13.1: https://youtu.be/OuJerKzV5T0?t=11292 */ -- Crea una tabla llamada "persons" con nombre de columna (atributos) de tipo int, varchar y date CREATE TABLE persons ( id int, name varchar(100), age int, email varchar(50), created date ); /* CONSTRAINTS: Restricciones */ /* NOT NULL Lección 13.2: https://youtu.be/OuJerKzV5T0?t=11619 */ -- NOT NULL: Obliga a que el campo id posea siempre un valor no nulo CREATE TABLE persons2 ( id int NOT NULL, name varchar(100) NOT NULL, age int, email varchar(50), created date ); /* UNIQUE Lección 13.3: https://youtu.be/OuJerKzV5T0?t=11787 */ -- UNIQUE: Obliga a que el campo id posea valores diferentes CREATE TABLE persons3 ( id int NOT NULL, name varchar(100) NOT NULL, age int, email varchar(50), created datetime, UNIQUE(id) ); /* PRIMARY KEY Lección 13.4: https://youtu.be/OuJerKzV5T0?t=11911 */ -- PRIMARY KEY: Establece el campo id como clave primaria para futuras relaciones con otras tablas CREATE TABLE persons4 ( id int NOT NULL, name varchar(100) NOT NULL, age int, email varchar(50), created datetime, UNIQUE(id), PRIMARY KEY(id) ); /* CHECK Lección 13.5: https://youtu.be/OuJerKzV5T0?t=12121 */ -- CHECK: Establece que el campo age sólo podrá contener valores mayores o iguales a 18 CREATE TABLE persons5 ( id int NOT NULL, name varchar(100) NOT NULL, age int, email varchar(50), created datetime, UNIQUE(id), PRIMARY KEY(id), CHECK(age>=18) ); /* DEFAULT Lección 13.6: https://youtu.be/OuJerKzV5T0?t=12243 */ -- DEFAULT: Establece un valor por defecto en el campo created correspondiente a la fecha del sistema CREATE TABLE persons6 ( id int NOT NULL, name varchar(100) NOT NULL, age int, email varchar(50), created datetime DEFAULT CURRENT_TIMESTAMP(), UNIQUE(id), PRIMARY KEY(id), CHECK(age>=18) ); /* AUTO INCREMENT Lección 13.7: https://youtu.be/OuJerKzV5T0?t=12362 */ -- AUTO_INCREMENT: Indica que el campo id siempre se va a incrementar en 1 con cada nuevo inserto CREATE TABLE persons7 ( id int NOT NULL AUTO_INCREMENT, name varchar(100) NOT NULL, age int, email varchar(50), created datetime DEFAULT CURRENT_TIMESTAMP(), UNIQUE(id), PRIMARY KEY(id), CHECK(age>=18) ); ================================================ FILE: 04_Tables/02_drop_table.sql ================================================ /* DROP TABLE Lección 13.8: https://youtu.be/OuJerKzV5T0?t=12412 */ -- Elimina la tabla llamada "persons8" DROP TABLE persons8; ================================================ FILE: 04_Tables/03_alter_table.sql ================================================ /* ALTER TABLE Lección 13.9: https://youtu.be/OuJerKzV5T0?t=12461 */ /* ADD Lección 13.10: https://youtu.be/OuJerKzV5T0?t=12578 */ -- ADD: Añade un nuevo atributo surname a la tabla "persons8" ALTER TABLE persons8 ADD surname varchar(150); /* RENAME COLUMN Lección 13.11: https://youtu.be/OuJerKzV5T0?t=12624 */ -- RENAME COLUMN: Renombra el atributo surname a description en la tabla "persons8" ALTER TABLE persons8 RENAME COLUMN surname TO description; /* MODIFY COLUMN Lección 13.12: https://youtu.be/OuJerKzV5T0?t=12675 */ -- MODIFY COLUMN: Modifica el tipo de dato del atributo description en la tabla "persons8" ALTER TABLE persons8 MODIFY COLUMN description varchar(250); /* DROP COLUMN Lección 13.13: https://youtu.be/OuJerKzV5T0?t=12712 */ -- DROP COLUMN: Elimina el atributo description en la tabla "persons8" ALTER TABLE persons8 DROP COLUMN description; ================================================ FILE: 04_Tables/04_relationships.sql ================================================ /* TIPOS DE RELACIONES */ /* Relación 1:1 (uno a uno) Lección 15.1: https://youtu.be/OuJerKzV5T0?t=13490 Relación que indica que un registro en la tabla A se relaciona con un sólo registro en la tabla B y viceversa. */ -- El campo user_id de la tabla "dni" es clave foránea de la clave primaria user_id de la tabla "users" -- (Un usuario sólo puede tener un DNI. Un DNI sólo puede estar asociado a un usuario) CREATE TABLE dni( dni_id int AUTO_INCREMENT PRIMARY KEY, dni_number int NOT NULL, user_id int, UNIQUE(dni_id), FOREIGN KEY(user_id) REFERENCES users(user_id) ); /* Relación 1:N (uno a muchos) Lección 15.2: https://youtu.be/OuJerKzV5T0?t=13732 Relación que indica que un registro en la tabla A puede tener varios registros relacionados en la tabla B, pero un registro en la tabla B se relaciona con un sólo registro en la tabla A. */ CREATE TABLE companies( company_id int AUTO_INCREMENT PRIMARY KEY, name varchar(100) NOT NULL ); ALTER TABLE users ADD company_id int; -- El campo company_id de la tabla "users" es clave foránea de la clave primaria company_id de la tabla "companies" -- (Un empleado (usuario) sólo puede tener una empresa, pero una empresa puede tener muchos empleados (usuarios)) ALTER TABLE users ADD CONSTRAINT fk_companies FOREIGN KEY(company_id) REFERENCES companies(company_id) /* Relación N:M (muchos a muchos) Lección 15.3: https://youtu.be/OuJerKzV5T0?t=14313 Relación que indica que un un registro en la tabla A puede relacionarse con varios registros en la tabla B y viceversa. Requiere una tabla intermedia o de unión para establecer la relación. */ CREATE TABLE languages( language_id int AUTO_INCREMENT PRIMARY KEY, name varchar(100) NOT NULL ); -- El campo user_id y language_id de la tabla intermedia "users_languages" es clave foránea de las -- claves primarias user_id de la tabla "users" y de language_id de la tabla "languages" -- Un usuario puede conoces muchos lenguajes. Un lenguaje puede ser conocido por muchos usuarios. CREATE TABLE users_languages( users_language_id int AUTO_INCREMENT PRIMARY KEY, user_id int, language_id int, FOREIGN KEY(user_id) REFERENCES users(user_id), FOREIGN KEY(language_id) REFERENCES languages(language_id), UNIQUE (user_id, language_id) ); /* Relación de Auto-Referencia Relación que indica que un un registro en la tabla A puede relacionarse con otro registro de la tabla A. */ /* INSERT y UPDATE para trabajar con JOIN */ /* 1:1 Lección 16.1: https://youtu.be/OuJerKzV5T0?t=14994 */ -- "dni" (Relación 1:1) INSERT INTO dni (dni_number, user_id) VALUES (11111111, 1); INSERT INTO dni (dni_number, user_id) VALUES (22222222, 2); INSERT INTO dni (dni_number, user_id) VALUES (33333333, 3); INSERT INTO dni (dni_number) VALUES (44444444); /* 1:N Lección 16.2: https://youtu.be/OuJerKzV5T0?t=15203 */ -- "companies" y "users" (Relación 1:N) INSERT INTO companies (name) VALUES ('MoureDev'); INSERT INTO companies (name) VALUES ('Apple'); INSERT INTO companies (name) VALUES ('Google'); UPDATE users SET company_id = 1 WHERE user_id = 1; UPDATE users SET company_id = 2 WHERE user_id = 3; UPDATE users SET company_id = 3 WHERE user_id = 4; UPDATE users SET company_id = 1 WHERE user_id = 7; /* N:M Lección 16.3: https://youtu.be/OuJerKzV5T0?t=15474 */ -- "languages" y "users_languages" (Relación N:M) INSERT INTO languages (name) VALUES ('Swift'); INSERT INTO languages (name) VALUES ('Kotlin'); INSERT INTO languages (name) VALUES ('JavaScript'); INSERT INTO languages (name) VALUES ('Java'); INSERT INTO languages (name) VALUES ('Python'); INSERT INTO languages (name) VALUES ('C#'); INSERT INTO languages (name) VALUES ('COBOL'); INSERT INTO users_languages (user_id, language_id) VALUES (1, 1); INSERT INTO users_languages (user_id, language_id) VALUES (1, 2); INSERT INTO users_languages (user_id, language_id) VALUES (1, 5); INSERT INTO users_languages (user_id, language_id) VALUES (2, 3); INSERT INTO users_languages (user_id, language_id) VALUES (2, 5); ================================================ FILE: 05_Join/01_inner_join.sql ================================================ /* INNER JOIN (JOIN) Lección 17.1: https://youtu.be/OuJerKzV5T0?t=16101 */ -- Realiza un JOIN de manera incorrecta, ya que no existe un campo de relación SELECT * FROM users INNER JOIN dni; -- Obtiene los datos de los usuarios que tienen un dni SELECT * FROM users INNER JOIN dni ON users.user_id = dni.user_id; -- Obtiene los datos de los usuarios que tienen un dni (JOIN es lo mismo que INNER JOIN) SELECT * FROM users JOIN dni ON users.user_id = dni.user_id; -- Obtiene el nombre y el dni de los usuarios que tienen un dni y los ordena por edad SELECT name, dni_number FROM users JOIN dni ON users.user_id = dni.user_id ORDER BY age ASC; -- Obtiene los datos de los usuarios que tienen empresa SELECT * FROM users JOIN companies ON users.company_id = companies.company_id; -- Obtiene los datos de las empresas que tienen usuarios SELECT * FROM companies JOIN users ON users.company_id = companies.company_id; -- Obtiene el nombre de las empresas junto al nombre de sus usuarios SELECT companies.name, users.name FROM companies JOIN users ON companies.company_id = users.company_id; -- Obtiene los nombres de usuarios junto a los lenguajes que conocen SELECT users.name, languages.name FROM users_languages JOIN users ON users_languages.user_id=users.user_id JOIN languages ON users_languages.language_id=languages.language_id; -- Obtiene los nombres de usuarios junto a los lenguajes que conocen (utilizando otro orden de relación entre tablas) SELECT users.name, languages.name FROM users JOIN users_languages ON users.user_id=users_languages.user_id JOIN languages ON users_languages.language_id=languages.language_id; ================================================ FILE: 05_Join/02_left_join.sql ================================================ /* LEFT JOIN Lección 17.2: https://youtu.be/OuJerKzV5T0?t=17045 */ -- Obtiene los datos de todos los usuarios junto a su dni (lo tenga o no) SELECT * FROM users LEFT JOIN dni ON users.user_id = dni.user_id; -- Obtiene el nombre de todos los usuarios junto a su dni (lo tenga o no) SELECT name, dni_number FROM users LEFT JOIN dni ON users.user_id = dni.user_id; -- Obtiene todos los dni junto al nombre de su usuario (lo tenga o no) SELECT name, dni_number FROM dni LEFT JOIN users ON users.user_id = dni.user_id; -- Obtiene el nombre de todos los usuarios junto a sus lenguajes (los tenga o no) SELECT users.name, languages.name FROM users LEFT JOIN users_languages ON users.user_id=users_languages.user_id LEFT JOIN languages ON users_languages.language_id=languages.language_id; ================================================ FILE: 05_Join/03_right_join.sql ================================================ /* RIGHT JOIN Lección 17.3: https://youtu.be/OuJerKzV5T0?t=17399 */ -- Obtiene todos los dni junto a su usuario (lo tenga o no) SELECT * FROM users RIGHT JOIN dni ON users.user_id = dni.user_id; -- Obtiene todos los dni junto al nombre de su usuario (lo tenga o no) SELECT name, dni_number FROM users RIGHT JOIN dni ON users.user_id = dni.user_id; -- Obtiene el nombre de todos los usuarios junto a su dni (lo tenga o no) SELECT name, dni_number FROM dni RIGHT JOIN users ON users.user_id = dni.user_id; -- Obtiene el nombre de todos los lenguajes junto a sus usuarios (los tenga o no) SELECT users.name, languages.name FROM users RIGHT JOIN users_languages ON users.user_id=users_languages.user_id RIGHT JOIN languages ON users_languages.language_id=languages.language_id; ================================================ FILE: 05_Join/04_union.sql ================================================ /* UNION (FULL JOIN) Lección 17.4: https://youtu.be/OuJerKzV5T0?t=17536 */ -- UNION elimina duplicados -- Obtiene todos los id de usuarios de las tablas dni y usuarios (exista o no relación) SELECT users.user_id AS u_user_id, dni.user_id AS d_user_id FROM users LEFT JOIN dni ON users.user_id = dni.user_id UNION SELECT users.user_id AS user_id, dni.user_id AS d_user_id FROM users RIGHT JOIN dni ON users.user_id = dni.user_id; -- Obtiene todos los datos de las tablas dni y usuarios (exista o no relación) SELECT * FROM users LEFT JOIN dni ON users.user_id = dni.user_id UNION SELECT * FROM users RIGHT JOIN dni ON users.user_id = dni.user_id; -- UNION ALL mantiene duplicados ================================================ FILE: 06_Advanced/01_index.sql ================================================ /* INDEX Lección 18.1: https://youtu.be/OuJerKzV5T0?t=18219 */ -- Crea un índice llamado "idx_name" en la tabla "users" asociado al campo "name" CREATE INDEX idx_name ON users(name); -- Crea un índice único llamado "idx_name" en la tabla "users" asociado al campo "name" CREATE UNIQUE INDEX idx_name ON users(name); -- Crea un índice llamado "idx_name_surname" en la tabla "users" asociado a los campos "name" y "surname" CREATE UNIQUE INDEX idx_name_surname ON users(name, surname); -- Elimina el índice llamado "idx_name" DROP INDEX idx_name ON users; ================================================ FILE: 06_Advanced/02_triggers.sql ================================================ /* TRIGGERS Lección 18.2: https://youtu.be/OuJerKzV5T0?t=18961 */ -- Crea una tabla de historial para usar en el ejemplo CREATE TABLE `hello_mysql`.`email_history` ( `email_history_id` INT NOT NULL AUTO_INCREMENT, `user_id` INT NOT NULL, `email` VARCHAR(100) NULL, PRIMARY KEY (`email_history_id`), UNIQUE INDEX `email_history_id_UNIQUE` (`email_history_id` ASC) VISIBLE); -- Crea un trigger llamado "tg_email" que guarda el email previo en la tabla "email_history" siempre -- que se actualiza el campo "email" en la tabla "users" -- DELIMITER es una directiva que sirve para cambiar el delimitador de instrucciones SQL, que por defecto es ; -- Se utiliza cuando se define un bloque de código como un procedimiento donde se requieren múltiples -- instrucciones SQL terminadas con punto y coma dentro de un mismo bloque. DELIMITER // CREATE TRIGGER tg_email AFTER UPDATE ON users FOR EACH ROW BEGIN IF OLD.email <> NEW.email THEN INSERT INTO email_history (user_id, email) VALUES (OLD.user_id, OLD.email); END IF; END// -- Actualiza el campo "email" del usuario 1 la tabla "users" para probar el trigger UPDATE users SET email = 'mouredev@gmail.com' WHERE user_id = 1 -- Elimina el trigger llamado "tg_email" DROP TRIGGER tg_email; ================================================ FILE: 06_Advanced/03_views.sql ================================================ /* VIEWS Lección 18.3: https://youtu.be/OuJerKzV5T0?t=19663 */ -- Crea unaa vista llamada "v_adult_users" con los nombres y edades de usuarios de la table "users" -- que tienen una edad igual o mayor a 18 años. CREATE VIEW v_adult_users AS SELECT name, age FROM users WHERE age >= 18; SELECT * FROM v_adult_users; -- Elimina la vista llamada "v_adult_users" DROP VIEW v_adult_users; ================================================ FILE: 06_Advanced/04_stored_procedures.sql ================================================ /* STORED PROCEDURES Lección 18.4: https://youtu.be/OuJerKzV5T0?t=20033 */ -- Crea un procedimiento almacenado llamado "p_all_users" que obtiene todos los datos de "users" DELIMITER // CREATE PROCEDURE p_all_users() BEGIN SELECT * FROM users; END// -- Invoca al procedimiento almacenado llamado "p_all_users" CALL p_all_users; -- Crea un procedimiento almacenado llamado "p_age_users" parametrizado para -- obtener usuarios con edad variable DELIMITER // CREATE PROCEDURE p_age_users(IN age_param int) BEGIN SELECT * FROM users WHERE age = age_param; END// -- Invoca al procedimiento almacenado llamado "p_age_users" con un parámetro de valor 30 CALL p_age_users(30); -- Elimina el procedimiento almacenado llamado "p_age_users" DROP PROCEDURE p_age_users; ================================================ FILE: 06_Advanced/05_transactions.sql ================================================ /* TRANSACTIONS Lección 18.5: https://youtu.be/OuJerKzV5T0?t=20501 */ -- Inicia una nueva transacción. Desde este punto, todas las modificaciones realizadas en la -- base de datos son temporales y solo son visibles dentro de esta transacción START TRANSACTION -- Finaliza una transacción con éxito. Cuando se ejecuta, todos los cambios realizados en la -- base de datos durante la transacción actual se hacen permanentes y visibles COMMIT -- Deshace las operaciones realizadas en una transacción, revirtiendo la base de datos -- al estado en que se encontraba antes de iniciar la transacción ROLLBACK ================================================ FILE: 06_Advanced/06_connectors.py ================================================ # CONNECTORS # Lección 19.1: https://youtu.be/OuJerKzV5T0?t=20876 # Lección 19.2: https://youtu.be/OuJerKzV5T0?t=21149 # Ejemplo de conexión desde Python a una base de datos local # Se ejemplifica cómo evitar SQL INJECTION import mysql.connector def print_user(user): config = { "host": "127.0.0.1", "port": "3306", "database": "hello_mysql", "user": "root", "password": "root1234" } # config = { # "host": "bpw0hq9h09e7mqicjhtl-mysql.services.clever-cloud.com", # "port": "3306", # "database": "bpw0hq9h09e7mqicjhtl", # "user": "uqzby88erlhvkrty", # "password": "oePXiCOHdU1WRV80NPyv" # } connection = mysql.connector.connect(**config) cursor = connection.cursor() query = "SELECT * FROM users WHERE name=%s;" print(query) cursor.execute(query, (user,)) result = cursor.fetchall() for row in result: print(row) cursor.close() connection.close() print_user("Brais") # print_user("'; UPDATE users SET age = '15' WHERE user_id = 1; --") ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # Hello SQL [![SQL](https://img.shields.io/badge/MySQL-8.0+-f29221?style=for-the-badge&logo=mysql&logoColor=white&labelColor=101010)](https://mysql.com) [![SQL](https://img.shields.io/badge/PostgreSQL-16+-699eca?style=for-the-badge&logo=postgresql&logoColor=white&labelColor=101010)](https://postgresql.org) ## Curso completo para aprender los fundamentos del lenguaje SQL y bases de datos relacionales ![](./Images/header.jpg) ### 7 horas | +80 lecciones | +50 comandos | con código | desde cero | completo | gratis ### Proyecto realizado durante emisiones en directo desde [Twitch](https://twitch.tv/mouredev) > ##### Si consideras útil el curso, apóyalo haciendo "★ Star" en el repositorio. ¡Gracias! ## Curso completo en vídeo **Este es el curso completo en [vídeo](https://youtu.be/OuJerKzV5T0) de 7 horas en YouTube asociado al código de este repositorio.** ## Lecciones y código [INTRODUCCIÓN](https://youtu.be/OuJerKzV5T0) 1. [Bases de datos SQL](https://youtu.be/OuJerKzV5T0?t=234) 2. [Sistema de gestión de base de datos](https://youtu.be/OuJerKzV5T0?t=1011) 3. [Fundamentos de SQL y bases de datos](https://youtu.be/OuJerKzV5T0?t=1347) 4. [Configuración e instalación](https://youtu.be/OuJerKzV5T0?t=2753) 5. [Primeros pasos](https://youtu.be/OuJerKzV5T0?t=3282) 6. [Conexión y cliente SQL](https://youtu.be/OuJerKzV5T0?t=3555) 7. [Inicialización de datos](https://youtu.be/OuJerKzV5T0?t=4381) 8. [Consulta de datos: `SELECT`](https://youtu.be/OuJerKzV5T0?t=5618) ➔ [[Código]](./01_Reading/01_select.sql) 9. [Modificadores: Parte 1](https://youtu.be/OuJerKzV5T0?t=6074) 1. [`DISTINCT`](https://youtu.be/OuJerKzV5T0?t=6089) ➔ [[Código]](./01_Reading/02_distinct.sql) 2. [`WHERE`](https://youtu.be/OuJerKzV5T0?t=6384) ➔ [[Código]](./01_Reading/03_where.sql) 3. [`ORDER BY`](https://youtu.be/OuJerKzV5T0?t=6592) ➔ [[Código]](./01_Reading/04_order_by.sql) 4. [`LIKE`](https://youtu.be/OuJerKzV5T0?t=6894) ➔ [[Código]](./01_Reading/05_like.sql) 5. [`AND, OR, NOT`](https://youtu.be/OuJerKzV5T0?t=7194) ➔ [[Código]](./01_Reading/06_and_or_not.sql) 6. [`LIMIT`](https://youtu.be/OuJerKzV5T0?t=7395) ➔ [[Código]](./01_Reading/07_limit.sql) 10. [Modificadores: Parte 2](https://youtu.be/OuJerKzV5T0?t=7503) 1. [`COMMENTS`](https://youtu.be/OuJerKzV5T0?t=7512) ➔ [[Código]](./01_Reading/00_comments.sql) 2. [`NULL`](https://youtu.be/OuJerKzV5T0?t=7615) ➔ [[Código]](./01_Reading/08_null.sql) 3. [`MIN, MAX`](https://youtu.be/OuJerKzV5T0?t=7834) ➔ [[Código]](./01_Reading/09_min_max.sql) 4. [`COUNT`](https://youtu.be/OuJerKzV5T0?t=8043) ➔ [[Código]](./01_Reading/10_count.sql) 5. [`SUM`](https://youtu.be/OuJerKzV5T0?t=8128) ➔ [[Código]](./01_Reading/11_sum.sql) 6. [`AVG`](https://youtu.be/OuJerKzV5T0?t=8293) ➔ [[Código]](./01_Reading/12_avg.sql) 7. [`IN`](https://youtu.be/OuJerKzV5T0?t=8335) ➔ [[Código]](./01_Reading/13_in.sql) 8. [`BETWEEN`](https://youtu.be/OuJerKzV5T0?t=8559) ➔ [[Código]](./01_Reading/14_between.sql) 9. [`ALIAS`](https://youtu.be/OuJerKzV5T0?t=8667) ➔ [[Código]](./01_Reading/15_alias.sql) 10. [`CONCAT`](https://youtu.be/OuJerKzV5T0?t=8826) ➔ [[Código]](./01_Reading/16_concat.sql) 11. [`GROUP BY`](https://youtu.be/OuJerKzV5T0?t=8960) ➔ [[Código]](./01_Reading/17_group_by.sql) 12. [`HAVING`](https://youtu.be/OuJerKzV5T0?t=9265) ➔ [[Código]](./01_Reading/18_having.sql) 13. [`CASE`](https://youtu.be/OuJerKzV5T0?t=9486) ➔ [[Código]](./01_Reading/19_case.sql) 14. [`IFNULL`](https://youtu.be/OuJerKzV5T0?t=10023) ➔ [[Código]](./01_Reading/08_null.sql) 15. [Otros modificadores](https://youtu.be/OuJerKzV5T0?t=10191) 11. [Escritura de datos](https://youtu.be/OuJerKzV5T0?t=10289) 1. [`INSERT`](https://youtu.be/OuJerKzV5T0?t=10370) ➔ [[Código]](./02_Writing/01_insert.sql) 2. [`UPDATE`](https://youtu.be/OuJerKzV5T0?t=10621) ➔ [[Código]](./02_Writing/02_update.sql) 3. [`DELETE`](https://youtu.be/OuJerKzV5T0?t=10920) ➔ [[Código]](./02_Writing/03_delete.sql) 12. [Administración de la base de datos](https://youtu.be/OuJerKzV5T0?t=11021) 1. [`CREATE DATABASE`](https://youtu.be/OuJerKzV5T0?t=11064) ➔ [[Código]](./03_Database/01_create_database.sql) 2. [`DROP DATABASE`](https://youtu.be/OuJerKzV5T0?t=11180) ➔ [[Código]](./03_Database/02_drop_database.sql) 13. [Administración de tablas](https://youtu.be/OuJerKzV5T0?t=11021) 1. [`CREATE TABLE`](https://youtu.be/OuJerKzV5T0?t=11292) ➔ [[Código]](./04_Tables/01_create_table.sql) 2. [`NOT NULL`](https://youtu.be/OuJerKzV5T0?t=11619) ➔ [[Código]](./04_Tables/01_create_table.sql) 3. [`UNIQUE`](https://youtu.be/OuJerKzV5T0?t=11787) ➔ [[Código]](./04_Tables/01_create_table.sql) 4. [`PRIMARY KEY`](https://youtu.be/OuJerKzV5T0?t=11911) ➔ [[Código]](./04_Tables/01_create_table.sql) 5. [`CHECK`](https://youtu.be/OuJerKzV5T0?t=12121) ➔ [[Código]](./04_Tables/01_create_table.sql) 6. [`DEFAULT`](https://youtu.be/OuJerKzV5T0?t=12243) ➔ [[Código]](./04_Tables/01_create_table.sql) 7. [`AUTO INCREMENT`](https://youtu.be/OuJerKzV5T0?t=12362) ➔ [[Código]](./04_Tables/01_create_table.sql) 8. [`DROP TABLE`](https://youtu.be/OuJerKzV5T0?t=12412) ➔ [[Código]](./04_Tables/02_drop_table.sql) 9. [`ALTER TABLE`](https://youtu.be/OuJerKzV5T0?t=12461) ➔ [[Código]](./04_Tables/03_alter_table.sql) 10. [`ADD`](https://youtu.be/OuJerKzV5T0?t=12578) ➔ [[Código]](./04_Tables/03_alter_table.sql) 11. [`RENAME COLUMN`](https://youtu.be/OuJerKzV5T0?t=12624) ➔ [[Código]](./04_Tables/03_alter_table.sql) 12. [`MODIFY COLUMN`](https://youtu.be/OuJerKzV5T0?t=12675) ➔ [[Código]](./04_Tables/03_alter_table.sql) 13. [`DROP COLUMN`](https://youtu.be/OuJerKzV5T0?t=12712) ➔ [[Código]](./04_Tables/03_alter_table.sql) 14. [Relaciones entre tablas](https://youtu.be/OuJerKzV5T0?t=12781) 1. [RELACIÓN `1:1`](https://youtu.be/OuJerKzV5T0?t=12852) 2. [RELACIÓN `1:N`](https://youtu.be/OuJerKzV5T0?t=13117) 3. [RELACIÓN `N:M`](https://youtu.be/OuJerKzV5T0?t=13208) 4. [AUTOREFERENCIA](https://youtu.be/OuJerKzV5T0?t=13343) 15. [Creación de tablas relacionadas](https://youtu.be/OuJerKzV5T0?t=13428) 1. [TABLAS `1:1`](https://youtu.be/OuJerKzV5T0?t=13490) ➔ [[Código]](./04_Tables/04_relationships.sql) 2. [TABLAS `1:N`](https://youtu.be/OuJerKzV5T0?t=13732) ➔ [[Código]](./04_Tables/04_relationships.sql) 3. [TABLAS `N:M`](https://youtu.be/OuJerKzV5T0?t=14313) ➔ [[Código]](./04_Tables/04_relationships.sql) 16. [Almacenamiento de datos relacionados](https://youtu.be/OuJerKzV5T0?t=14635) 1. [DATOS `1:1`](https://youtu.be/OuJerKzV5T0?t=14994) ➔ [[Código]](./04_Tables/04_relationships.sql) 2. [DATOS `1:N`](https://youtu.be/OuJerKzV5T0?t=15203) ➔ [[Código]](./04_Tables/04_relationships.sql) 3. [DATOS `N:M`](https://youtu.be/OuJerKzV5T0?t=15474) ➔ [[Código]](./04_Tables/04_relationships.sql) 17. [Consulta de datos relacionados](https://youtu.be/OuJerKzV5T0?t=16013) 1. [`INNER JOIN`](https://youtu.be/OuJerKzV5T0?t=16101) ➔ [[Código]](./05_Join/01_inner_join.sql) 2. [`LEFT JOIN`](https://youtu.be/OuJerKzV5T0?t=17045) ➔ [[Código]](./05_Join/02_left_join.sql) 3. [`RIGHT JOIN`](https://youtu.be/OuJerKzV5T0?t=17399) ➔ [[Código]](./05_Join/03_right_join.sql) 4. [`UNION`](https://youtu.be/OuJerKzV5T0?t=17536) ➔ [[Código]](./05_Join/04_union.sql) 18. [Conceptos avanzados](https://youtu.be/OuJerKzV5T0?t=18196) 1. [`INDEX`](https://youtu.be/OuJerKzV5T0?t=18219) ➔ [[Código]](./06_Advanced/01_index.sql) 2. [`TRIGGER`](https://youtu.be/OuJerKzV5T0?t=18961) ➔ [[Código]](./06_Advanced/02_triggers.sql) 3. [`VIEW`](https://youtu.be/OuJerKzV5T0?t=19663) ➔ [[Código]](./06_Advanced/03_views.sql) 4. [`STORED PROCEDURE`](https://youtu.be/OuJerKzV5T0?t=20033) ➔ [[Código]](./06_Advanced/04_stored_procedures.sql) 5. [TRANSACCIONES](https://youtu.be/OuJerKzV5T0?t=20501) ➔ [[Código]](./06_Advanced/05_transactions.sql) 6. [CONCURRENCIA](https://youtu.be/OuJerKzV5T0?t=20701) 19. [Conexión desde código](https://youtu.be/OuJerKzV5T0?t=20847) 1. [CONECTORES](https://youtu.be/OuJerKzV5T0?t=20876) ➔ [[Código]](./06_Advanced/06_connectors.py) 2. [SQL INJECTION](https://youtu.be/OuJerKzV5T0?t=21149) ➔ [[Código]](./06_Advanced/06_connectors.py) 20. [Otros clientes SQL](https://youtu.be/OuJerKzV5T0?t=21641) 21. [PostgresSQL](https://youtu.be/OuJerKzV5T0?t=22070) 22. [Despliegue en la nube](https://youtu.be/OuJerKzV5T0?t=23214) 23. [Próximos pasos](https://youtu.be/OuJerKzV5T0?t=24283) [CONCLUSIONES](https://youtu.be/OuJerKzV5T0?t=24678) Durante el curso aprenderemos los fundamentos del lenguaje SQL y las bases de datos relacionales con ejemplos prácticos. Nos centraremos en MySQL para llevar a cabo las clases, ya que es uno de los más usados en enseñanza y a nivel profesional. También utilizaremos PostgreSQL, por ser una de las bases de datos más populares de la actualidad. De todas formas, no debe preocuparte el motor de bases de datos utilizado, ya que SQL es un lenguaje estándar, por lo que se utilizará prácticamente igual en todas ellas. Una vez lo conozcas no tendrá dificultad alguna llevar esos conocimientos a otros sistemas. Todo el código creado durante el curso está disponible para que puedas consultarlo junto a su explicación. > En el servidor de la comunidad de [Discord](https://discord.gg/mouredev) dispones de un canal llamado "💾bases-de-datos" para que puedas comentar lo que quieras. ## Enlaces de interés * [Documentación SQL](https://www.w3schools.com/sql/default.asp) * [MySQL](https://mysql.com) * [Descarga MySQL](https://dev.mysql.com/downloads/mysql/) * [CLI MySQL](https://dev.mysql.com/doc/refman/8.0/en/mysql.html) * [MySQL Workbench](https://dev.mysql.com/downloads/workbench) * [PostgreSQL](https://www.postgresql.org) * [Clever Cloud](https://www.clever-cloud.com) ## Únete al campus de programación de la comunidad ![https://mouredev.pro](./Images/pro.jpg) #### Te presento [mouredev pro](https://mouredev.pro), mi proyecto más importante para ayudarte a estudiar programación y desarrollo de software de manera diferente. > **¿Buscas un extra?** Aquí encontrarás mis cursos editados por lecciones individuales, para avanzar a tu ritmo y guardar el progreso. También dispondrás de ejercicios y correcciones, test para validar tus conocimientos, examen y certificado público de finalización, soporte, foro de estudiantes, reunionnes grupales, cursos exclusivos y mucho más. > > Entra en **[mouredev.pro](https://mouredev.pro)** y utiliza el cupón **"PRO"** con un 10% de descuento en tu primera suscripción. ## ![https://mouredev.com](https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_emote.png) Hola, mi nombre es Brais Moure. ### Freelance full-stack iOS & Android engineer [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCxPD7bsocoAMq8Dj18kmGyQ?style=social)](https://youtube.com/mouredevapps?sub_confirmation=1) [![Twitch Status](https://img.shields.io/twitch/status/mouredev?style=social)](https://twitch.com/mouredev) [![Discord](https://img.shields.io/discord/729672926432985098?style=social&label=Discord&logo=discord)](https://mouredev.com/discord) [![Twitter Follow](https://img.shields.io/twitter/follow/mouredev?style=social)](https://twitter.com/mouredev) ![GitHub Followers](https://img.shields.io/github/followers/mouredev?style=social) ![GitHub Followers](https://img.shields.io/github/stars/mouredev?style=social) Soy ingeniero de software desde 2010. Desde 2018 combino mi trabajo desarrollando Apps con la creación de contenido formativo sobre programación y tecnología en diferentes redes sociales como **[@mouredev](https://moure.dev)**. Si quieres unirte a nuestra comunidad de desarrollo, aprender programación, mejorar tus habilidades y ayudar a la continuidad del proyecto, puedes encontrarnos en: [![Twitch](https://img.shields.io/badge/Twitch-Programación_en_directo-9146FF?style=for-the-badge&logo=twitch&logoColor=white&labelColor=101010)](https://twitch.tv/mouredev) [![Discord](https://img.shields.io/badge/Discord-Servidor_de_la_comunidad-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=101010)](https://mouredev.com/discord) [![Pro](https://img.shields.io/badge/Cursos-mouredev.pro-FF5500?style=for-the-badge&logo=gnometerminal&logoColor=white&labelColor=101010)](https://moure.dev) [![Link](https://img.shields.io/badge/Links_de_interés-moure.dev-14a1f0?style=for-the-badge&logo=Linktree&logoColor=white&labelColor=101010)](https://moure.dev) [![Web](https://img.shields.io/badge/GitHub-MoureDev-087ec4?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://github.com/mouredev)