Está en la página 1de 6

-- Semana 11: Backup, Ciberseguridad y Structured Query Language

-- Símbolo de la ESEN:
--El distintivo de la ESEN es el árbol de roble, que se caracteriza por su
fortaleza. Para la ESEN hay una clara asociación
--entre la fuerza del roble y la fuerza de la educación como elemento primordial
para el desarrollo económico y
-- social de El Salvador y de la región.

-- 1
--------------------------------Generar el backup de la base de
datos-----------------------------------------
-- Documentación: https://www.postgresql.org/docs/14/backup.html
-- Copias de seguridad y restauración de base de datos
-- Hacer la prueba con la configuración por defecto
-- Preferences- Binary Path-PostgreSQL14
-- En caso de que no sea la dirección correcta, habría que cambiarla a una
dirección como la de abajo
-- Verificar dirección: C:\Program Files\PostgreSQL\14\bin
-- Una vez que el backup con la configuración por defecto está hecho
-- Eliminamos la base de ordenes
-- Debemos crearla de nuevo para luego restaurar el backup que ya creamos

-- 2
----------------------------------------------
Ciberseguridad--------------------------------------------------
-- Ver las diapositivas
-- https://www.vpnmentor.com/blog/how-to-secure-website-database/
-- https://websitesecuritystore.com/blog/how-to-secure-database-from-cyber-attacks/

-- 3
------------------------------Creando usuario con acceso limitado a
Postgres----------------------------------
-- https://www.postgresqltutorial.com/postgresql-administration/
-- Documentación:
https://www.postgresqltutorial.com/postgresql-administration/postgresql-roles/
SELECT rolname FROM pg_roles;
-- Vamos a crear un rol que se pueda loguear
CREATE ROLE maria
LOGIN
PASSWORD 'password';
-- Luego vamos a darle permisos para que pueda ejecutar un Select en una tabla
-- No va a poder ejecutar otras acciones...
-- https://www.postgresqltutorial.com/postgresql-administration/postgresql-grant/
-- Haremos que tenga permiso de ver dos tablas
-- El usuario debe poder usar el esquema ord
GRANT USAGE ON SCHEMA ord TO maria;
-- GRANT some_or_all_privileges ON ALL TABLES TO role;
GRANT SELECT
ON ord.ciudades, ord.departamentos
TO maria;

SELECT current_database();

SELECT id_ciudad, ciudad, id_departamento


FROM ord.ciudades;
-- Documentación:
https://www.postgresqltutorial.com/postgresql-administration/postgresql-drop-role/
-- Dará mensaje de error:
drop role maria;
--Los objetos que son propiedad de María lo pasamos a propiedad de postgres
reassign owned by maria to postgres;
-- Lo que depende de María lo eliminamos (pero ya reasignamos lo dependiente de
ella a su usuario)
drop owned by maria;
-- Eliminamos el rol de María
drop role maria; -- Este código ya no debería dar error

----------------------------El Disneylandia para las ingenieras e ingenieros de


datos--------------------------------------
-- Los 7 tipos de códigos básicos de SQL + optimización de consultas
-- Orden de ejecución de códigos FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER,
LIMIT
-- Nuestra primera parada será en cómo obtener la tabla con la que trabajaremos...
--#################################################LOS
JOIN#################################################
-- Documentación: https://www.postgresql.org/docs/current/tutorial-join.html
-- https://www.javatpoint.com/postgresql-join
-- Insumo vital: El insumo para unir las tablas es el diagrama lógico. Debemos
abrir Draw.io
-- Comentar qué sucede en la realidad con este insumo vital...

-- Warning: Usted puede unir las tablas como usted desee, haga la prueba en su
sesión de estudio
-- Los join que veremos son Inner join, outer join, full outer
-- Tabla 1: Mandemos a llamar la data de departamentos
SELECT * FROM ord.departamentos; -- Este es el caso feliz de pañales Huggies, 1
sola tabla
-- Colocar nombre resumido de tabla y hacer consulta...

-- Tabla 2: Mandemos a llamar la data de departamentos


SELECT * FROM ord.ciudades;
-- Los tipos de Join
-- Lo clave es usar las llaves primarias y foráneas...
-------------------------------------------Caso
1---------------------------------------------------------------
-- Obteniendo solo los registros en común entre ambas tablas con INNER JOIN
SELECT *
FROM ord.departamentos dep
INNER JOIN ord.ciudades ciu ON dep.id_departamento=ciu.id_departamento;
-------------------------------------------Caso
2---------------------------------------------------------------
-- Obteniendo TODOS los registros DE LA TABLA 1 y los que están en común con la
tabla 2 con LEFT JOIN

-------------------------------------------Caso
3---------------------------------------------------------------
-- Obteniendo TODOS los registros entre ambas tablas con FULL OUTER JOIN

-- Los 3 casos lucen equivalentes, en este caso particular


-- No obstante, no lo son. El servidor ha unido las tablas de forma distinta.
-- El caso 4 solo se mencionará pues no se ocupa mucho en la realidad
-- Hint: Obtiene todos los registros de la tabla 2 y los que hay en común con la
tabla 1

-- Seleccionando los campos que queremos que aparezcan en el caso 1


-- Esto es aplicable en todos los casos
SELECT departamento, ciudad
FROM ord.departamentos dep
INNER JOIN ord.ciudades ciu ON dep.id_departamento=ciu.id_departamento;
-- En el caso anterior, ¿podemos diferenciar de qué tabla viene cada campo?
-- ¿Cómo hacemos para diferenciar de dónde proviene cada campo? Colocar consulta
arreglada en este espacio:

-- Uniendo tablas parte 2


-- Vamos a unir tablas de departamentos dep,ciudades ciu, clientes cli

-- Vamos a unir tablas la tabla anterior con transacciones tran, detalle


transacciones det_trans
-- En los campos a seleccionar vamos a usar tran.*,det_trans.*, ¿Qué obtenemos?

-----------------------------------------------
WHERE---------------------------------------------------
-- Documentación:
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-where/
-- Prestar atención a los símbolos con los que se puede armar
-- >, <, >=, <=, <> or !=, AND, OR, IN
--Tabla a usar (la misma tabla a la que deberíamos haber llegado en el paso
anterior)
SELECT dep.departamento, ciu.ciudad,cli.nombre,
cli.apellido,cli.direccion,tran.fecha
,det_trans.cantidad
FROM ord.departamentos dep
LEFT JOIN ord.ciudades ciu ON dep.id_departamento=ciu.id_departamento
LEFT JOIN ord.clientes cli ON ciu.id_ciudad=cli.id_ciudad
LEFT JOIN ord.transacciones tran ON cli.id_cliente=tran.id_cliente
LEFT JOIN ord.detalle_transacciones det_trans ON
tran.id_orden=det_trans.id_orden;

-- Vamos a mandar a llamar las transacciones de los clientes de 'San Salvador'


-- WHERE dep.departamento = 'San Salvador';

-- AND y OR: AND traducido a español es Y; OR traducido a español es O


-- El AND lo usamos porque queremos que ambas condiciones se cumplan
-- El OR lo usamos cuando queremos que al menos una de las condiciones se cumplan
-- #Llamemos las transacciones de los clientes de San Salvador y cuyas cantidades
compradas sean mayores o iguales a 9
-- miren el conector que usamos en el ejercicio: "Y". Por tanto, usaremos AND ya
traducido a lenguaje SQL
-- WHERE dep.departamento = 'San Salvador' AND det_trans.cantidad >= 9
-- La última línea de código debería quedar en el orden del texto para no perder el
hilo del ejercicio

-- _____En la realidad_____: Cuando ya estamos usando un montón de condiciones, se


suele escribir:
-- 1=1, y luego continuar con las otras condiciones. Esto incrementa la
legibilidad del código
/*WHERE 1=1
AND dep.departamento = 'San Salvador'
AND det_trans.cantidad >= 9;
*/
-- No hay variación en el resultado y el código quedará más legible
-- usando Where con Between: Return true if a value is between a range of values
-- Queremos obtener los valores de cantidad entre 6 y 12
-- WHERE det_trans.cantidad BETWEEN 6 AND 12

-- IN nos da la posibilidad de proveer una lista de valores con los cuales hacer el
filtrado de datos
-- Documentación:
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-in/
-- Obtengamos solo aquellos registros del año 2022
-- ¿De dónde podemos obtener el año de las transacciones para hacer el filtrado
-- (Imaginemos que tenemos transacciones de 10 años...)
-- WHERE EXTRACT(YEAR FROM tran.fecha) IN (2022)

-- Notar que In puede recibir un listado de nombres como ('Rivas', 'Lars')


-- O un listado de cantidades: (10,20,15)
-- Solo retornará aquellas filas con valores que estén en esa lista particular
-- ¿Qué pasará si queremos obtener todos los años excepto 2022? Hint: Usamos NOT en
la misma consulta

-- LIKE es un operador para identificar ciertos patrones en los textos


--Documentación: https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-
like/
-- Nos ayudará a encontrar textos que inicien, terminen o que tengan cierto texto
en medio
-- Los que cumplan esa condición serán retornados
-- Obtengamos aquellos registros cuyos nombres inicien con 'Cl'
-- WHERE cli.nombre LIKE 'Cl%'

-- Obtengamos aquellos registros cuyos nombres NO inicien con 'Cl'


-- Usamos NOT para traer las filas opuestas que identificó LIKE
-- WHERE cli.nombre NOT LIKE 'Cl%'

-- Obtengamos aquellos clientes cuyos apellidos terminen en rs


-- WHERE cli.apellido LIKE '%rs%'

-- IMPORTANTE: LIKE es un sucesor de las expresiones regulares...

----------------------------------------------------GROUP
BY----------------------------------------------------------
-- Documentación: https://www.postgresql.org/docs/14/functions-aggregate.html
-- Cálculos agregados de cajón: Suma, Promedio, Máximo, Mínimo
-- Armar una tabla con clientes, transacciones, detalle_transacciones y productos
-- Solo obtener los campos nombre, apellido y los campos necesarios para el cálculo
de la venta

-- Calcular las ventas por cliente y sumemos por nombre y apellido del cliente
-- Usaremos una función de agregación llamada SUM la cual nos ayudará a sumar
-- La venta es un campo calculado: Q*Precio
-- ¡Qué poderoso es el lenguaje SQL!

-- Calculemos la venta promedio con AVG()

-- Definamos la venta máxima y mínima por cliente por producto

----------------------------------------------------
HAVING----------------------------------------------------------
-- Documentación:
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-having/
-- Filtremos por aquellas ventas superiores a 200
-- Filtraremos por un cálculo ejecutado en el servidor
-- HAVING SUM(dtr.cantidad* pr.precio) >=200
-- Tabla a usar:
SELECT cl.nombre, cl.apellido, SUM(dtr.cantidad* pr.precio) AS Venta
FROM ord.clientes cl
LEFT JOIN ord.transacciones tr ON cl.id_cliente = tr.id_cliente
LEFT JOIN ord.detalle_transacciones dtr ON tr.id_orden = dtr.id_orden
LEFT JOIN ord.productos pr ON dtr.id_producto = pr.id_producto
GROUP BY cl.nombre, cl.apellido;
------------------------------------------SELECT, ORDER,
LIMIT----------------------------------------------------------
-- Son los últimos 3 comandos que el servidor ejecuta
-- SELECT, ORDER, LIMIT
-- Tabla a usar:
SELECT cl.nombre, cl.apellido, dtr.cantidad, pr.precio
FROM ord.clientes cl
LEFT JOIN ord.transacciones tr ON cl.id_cliente = tr.id_cliente
LEFT JOIN ord.detalle_transacciones dtr ON tr.id_orden = dtr.id_orden
LEFT JOIN ord.productos pr ON dtr.id_producto = pr.id_producto;
-- Por ejemplo, digamos que queremos ordenar la cantidad de menor a mayor
-- El orden puede ser ascendente con ASC y descendente con DESC
-- ORDER BY dtr.cantidad ASC

-- De mayor a menor
-- ORDER BY dtr.cantidad DESC

-- Tarea
-- ¿Qué ejemplo se les ocurre para ordenar los registros de forma alfabética?
-- ¿Tiene sentido que le pongamos ASC o DESC con campos de texto?

--Con LIMIT limitamos la cantidad de registros a mostrar al final


-- Con la consulta donde ordenamos los registros de mayor a menor, mostrar solo las
5 primeras filas
-- Tabla a usar
-- LIMIT 5

-- Mencionar su utilidad en la realidad


SELECT 'Orden de ejecución de códigos' AS Orden_Ejecucion;
SELECT 'FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER, LIMIT' AS Comandos;
-- Hemos comprobado que los códigos de SQL pueden combinarse para manejar de
distintas formas las tablas
-- Lo relevante es ser practicar para usar estos códigos estratégicamente
-- Ser capaz de disminuir el tiempo de ejecución de una consulta es una habilidad
valorada en el mercado laboral

También podría gustarte