Mostrando entradas con la etiqueta sql. Mostrar todas las entradas
Mostrando entradas con la etiqueta sql. Mostrar todas las entradas

jueves, 1 de diciembre de 2022

Base de datos para un punto de venta

El siguiente código es para dar soporte a un sistema de venta mediante la inclusión de una base de datos relacional llamada ventas.


Código SQL para MySQL

-- ------------------------------------
-- Tabla "categoria"
-- ------------------------------------
CREATE TABLE `ventas`.`categoria` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(50) NOT NULL , 
	`descripcion` TEXT NULL , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "producto"
-- ------------------------------------
CREATE TABLE `ventas`.`producto` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`nombre` VARCHAR(255) NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`descripcion` TEXT NULL , 
	`cantidad` INT NOT NULL ,
	`categoria` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_prod_cat
		FOREIGN KEY (categoria)
		REFERENCES categoria (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "cliente"
-- ------------------------------------
CREATE TABLE `ventas`.`cliente` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(150) NOT NULL , 
	`apellidos` VARCHAR(150) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "empleado"
-- ------------------------------------
CREATE TABLE `ventas`.`empleado` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`dni` VARCHAR(20) NOT NULL UNIQUE , 
	`nombres` VARCHAR(50) NOT NULL , 
	`paterno` VARCHAR(50) NOT NULL ,
	`materno` VARCHAR(50) NOT NULL , 
	`correo` VARCHAR(200) NOT NULL UNIQUE , 
	`telefono` VARCHAR(30) NOT NULL UNIQUE , 
	`clave` BLOB(200) NOT NULL ,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "venta"
-- ------------------------------------
CREATE TABLE `ventas`.`venta` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`cliente` INT NOT NULL , 
	`empleado` INT NOT NULL , 
	`monto` DECIMAL(10,2) NOT NULL , 
	`fecha` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_venta_cliente
		FOREIGN KEY (cliente)
		REFERENCES cliente (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_venta_empl
		FOREIGN KEY (empleado)
		REFERENCES empleado (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

-- ------------------------------------
-- Tabla "detalle"
-- ------------------------------------
CREATE TABLE `ventas`.`detalle` ( 
	`id` INT NOT NULL AUTO_INCREMENT , 
	`venta` INT NOT NULL , 
	`producto` INT NOT NULL , 
	`precio` DECIMAL(10,2) NOT NULL , 
	`cantidad` INT NOT NULL , 
	PRIMARY KEY (`id`),
	CONSTRAINT fk_detalle_venta
		FOREIGN KEY (venta)
		REFERENCES venta (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION ,
	CONSTRAINT fk_detalle_prod
		FOREIGN KEY (producto)
		REFERENCES producto (id)
		   ON DELETE NO ACTION
		   ON UPDATE NO ACTION
) ENGINE = InnoDB;

Datos para inicializar la base de datos

-- ------------------------------------
-- Datos de inicialización
-- ------------------------------------
-- 3 empleados
INSERT INTO empleado(dni, nombres, paterno,
	materno, correo, telefono, clave) VALUES 
('10001000','PAUL','GARCIA','MATTOS','paul@mail.com',
	'999888777',AES_ENCRYPT('2022','2022')),
('20002000','LORENA','HERRERA','SOTELO','lorena@mail.com',
	'999888666',AES_ENCRYPT('123456','123456')),
('30003000','DEMETRIO','GARCIA','GARCIA','demetrio@mail.com',
	'999888555',AES_ENCRYPT('ADMIN','ADMIN'));

-- 2 clientes
INSERT INTO cliente (dni, nombres, apellidos, correo) VALUES 
('10101010','EMILIA','MELGAREJO CHAVEZ','emilia@mail.com'),
('10201020','KAREN','TORRES ALVA','karen@mail.com');

-- 2 categorias
INSERT INTO categoria(nombre, descripcion) VALUES 
('BEBIDAS',null),('ENTRADAS','Lorem ipsum');

-- 5 productos
INSERT INTO producto(nombre, descripcion, precio, cantidad, categoria)  VALUES 
('Soda 500ml', 'Gaseosa de 500ml en botella de vidrio', 4.50, 100, 1),
('Soda 1l', 'Gaseosa de 1 litro retornable', 7.50, 50, 1),
('Chicha morada 500ml', 'Chicha morada de 500ml retornable', 3.50, 40, 1),
('Causa rellena - 250gr', 'Porción de causa de 250 gramos', 10.50, 10, 2),
('Papa a la huancaína', null, 11.00, 10, 2);

-- 3 Ventas
INSERT INTO venta(cliente,empleado,monto,fecha) VALUES
(1,1,100,"2022-04-03 14:00:45"),
(1,2,100,"2022-05-01 22:00:00"),
(2,2,100,"2022-08-13 21:30:45");

-- Detalle de cada venta
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(1,4,10,5),
(1,1,5,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(2,2,7.50,10),
(2,3,2.50,10);
INSERT INTO detalle(venta,producto,precio,cantidad) VALUES 
(3,4,10,10);

Vistas de la base de datos

-- VISTAS
-- ------------------------------------
-- productos_view
-- ------------------------------------
CREATE VIEW productos_view AS SELECT 
    p.id,
    p.nombre,
    p.precio,
    p.descripcion,
    p.cantidad,
    c.nombre AS categoria
FROM producto p INNER JOIN categoria c 
ON p.categoria = c.id;

-- ------------------------------------
-- venta_view
-- ------------------------------------
CREATE VIEW venta_view AS SELECT 
    v.id,
    CONCAT_WS(' ', c.nombres,c.apellidos) AS cliente,
    CONCAT_WS(' ', e.nombres,e.paterno,e.materno) AS empleado,
    v.fecha,
    v.monto,
    c.id AS id_cliente,
    e.id AS id_empleado
FROM venta v 
INNER JOIN cliente c ON v.cliente = c.id 
INNER JOIN empleado e ON v.empleado = e.id;

-- ------------------------------------
-- detalle_view
-- ------------------------------------
CREATE VIEW detalle_view AS SELECT 
    d.id,
    v.id AS venta,
    p.nombre AS producto,
    p.id AS id_producto,
    d.precio,
    d.cantidad
FROM detalle d 
INNER JOIN venta v ON d.venta = v.id 
INNER JOIN producto p ON d.producto = p.id;

viernes, 27 de noviembre de 2020

Creando una tabla en SQLite

Crear la base de datos

Se requiere de un programa que administre bases de datos de SQLite para crear las bases de datos y opcionalmente comprobar si los cambios realizados por aplicaciones externas funcionan. Se puede emplear alguno de estos u otros:

Las bases de datos de SQLite son archivos en lugar de un conjuntos de carpetas y archivos contenidos en un servidor, por lo cual no requieren un puerto.

Una vez instalado el programa, se selecciona la opción de agregar una base de datos

Se agrega una base de datos, se puede seleccionar una existente o crear una nueva

Se procede a crear una base de datos con la extensión "db" y luego realizar un test de conexión

Finalmente, aceptar


Crear la tabla

Mediante el programa se puede crear la tabla y las columnas seleccionando la base de datos:


Luego se debe seguir una serie de pasos para agregar columnas y configurarlas.

  1. Indicar el nombre de la tabla
  2. Agregar columnas
  3. Indicar el nombre de la columna y su tipo, adicionalmente el tamaño. Por ejemplo, columnas que contienen texto o números con decimales.
  4. Indicar los restricciones (constraints) como clave primaria, foránea, campo único, etc.
  5. En algunos casos es necesario agregar una configuración adicional a las restricciones.
  6. Por ejemplo, en los campos PRIMARY KEY de tipo entero, el autoincremento. Además, se puede colocar un nombre a la restricción. Por ejemplo, necesario para claves foráneas.
  7. Finalmente aplicar cambios y repetir el proceso para cada columna que se desee agregar.

Se confirman los cambios, luego aparece el código SQL generado que se puede guardar para tener un Script.



Código SQL

Si se desea, se puede colocar el código directamente, para ello se debe seleccionar el editor SQL como se muestra.

En el editor SQL se debe ingresar lo siguiente y ejecutar (F9 en Windows).

CREATE TABLE inquilinos (
    idinquilinos  INTEGER         PRIMARY KEY AUTOINCREMENT,
    dni           VARCHAR (8)     UNIQUE
                                  NOT NULL,
    nombres       VARCHAR (150)   NOT NULL,
    paterno       VARCHAR (150)   NOT NULL,
    materno       VARCHAR (150)   NOT NULL,
    telefono      VARCHAR (40),
    correo        VARCHAR (200),
    deuda         DECIMAL (10, 2) NOT NULL,
    fecha_ingreso DATE            NOT NULL
);

Finalmente, se podrá apreciar la estructura de la tabla dentro de la base de datos. Cabe recordar que la base de datos "blog.db" es un archivo que estará ubicado en la dirección seleccionada inicialmente y puede ser trasladado donde deseemos.


viernes, 25 de octubre de 2019

Diferencias SQL en MySQL, SQL Server, Oracle, PostgreSQL y SQLite

Veremos un diagrama EER de dos tablas y como se realizan las declaraciones de las mismas en los distintos gestores de bases de datos:

  • MySql y MariaBD
  • Oracle
  • SQL Server
  • PostgreSQL
  • SQLite


MySql y MariaBD

CREATE TABLE IF NOT EXISTS inquilinos (
  id INT NOT NULL AUTO_INCREMENT,
  dni VARCHAR(8) NOT NULL,
  nombres VARCHAR(150) NOT NULL,
  paterno VARCHAR(150) NOT NULL,
  materno VARCHAR(150) NOT NULL,
  telefono VARCHAR(40) NULL,
  correo VARCHAR(200) NULL,
  deuda DECIMAL(10,2) NOT NULL,
  fecha_ingreso DATE NOT NULL,
  PRIMARY KEY (idinquilinos),
  UNIQUE INDEX dni_UNIQUE (dni ASC),
  UNIQUE INDEX correo_UNIQUE (correo ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

INSERT INTO inquilinos(dni, nombres, paterno, materno, 
telefono, fecha_ingreso, correo, deuda) VALUES 
('31378082','LUISA', 'PAUCAR','NARRO','999888777',
'2018-01-28','lpaucar@mail.com',0.00),
('43331042','AUGUSTO','SOTOMAYOR','NARVAJO','900800700',
'2019-10-08','asoto@mail.com',0.00);

SELECT * FROM inquilinos


Oracle



SQL Server

CREATE TABLE inquilinos (
  id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
  dni VARCHAR(8) UNIQUE NOT NULL,
  nombres VARCHAR(150) NOT NULL,
  paterno VARCHAR(150) NOT NULL,
  materno VARCHAR(150) NOT NULL,
  telefono VARCHAR(40) NULL,
  correo VARCHAR(200) UNIQUE NOT NULL,
  deuda MONEY NOT NULL,
  fecha_ingreso DATE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO [inquilinos] ([dni],[nombres],[paterno],
   [materno],[telefono],[correo],[deuda],[fecha_ingreso]
   ) VALUES
	 ('31378082','LUISA', 'PAUCAR','NARRO','999888777',
        'lpaucar@mail.com',0.00,'2018-01-28'),
	 ('43331042','AUGUSTO','SOTOMAYOR','NARVAJO','900800700',
        'asoto@mail.com',0.00,'2019-10-08');

SELECT * FROM inquilinos


PostgreSQL

CREATE TABLE public."Usuarios"
(
    id serial NOT NULL,
    dni character(8) NOT NULL,
    nombres character varying(100) NOT NULL,
    apellidos character varying(150) NOT NULL,
    fecha_nacimiento date NOT NULL,
    PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
);

ALTER TABLE public."Usuarios"
    OWNER to postgres;


INSERT INTO Usuarios(
 dni, nombres, apellidos, fecha_nacimiento)
 VALUES ('71700011', 'Alan Damian', 'Toledo Higuchi', '1990-10-01');


SQLite

lunes, 21 de octubre de 2019

Creando una vista en MySQL

Diagrama EER

En este ejemplo vamos a implementar el código SQL para MySQL de la siguientes tablas que tenemos según el diagrama EER:



Lo que deseamos es crear una vista, esta vista actúa como una tabla que nosotros podemos personalizar a partir de consultas SELECT, son muy útiles para representar información de dos o más tablas que se relacionan en una sola. Ojo una vista no es una tabla propiamente dicha y solo se le puede aplicar SELECT, es decir solo ver sus datos, no se puede agregar, actualizar o eliminar registros de una vista, estos son registros de sus respectivas tablas y ahí se deben ejecutar dichas sentencias


Código SQL

Primero debemos tener la consulta que deseamos convertir en una vista, en este caso relacionar un pago con un inquilino, de forma que yo pueda ver el código del pago, el DNI del inquilino, sus nombres y apellidos en un solo campo, el pago que realizo, la fecha y hora (por separado) que lo hizo. El código resultante será el siguiente:

SELECT 
  pagos.idpagos,
  inquilinos.dni,
  CONCAT_WS(" ", inquilinos.nombres, inquilinos.paterno, inquilinos.materno),
  pagos.monto
  DATE(pagos.fecha),
  TIME(pagos.fecha)
FROM pagos INNER JOIN inquilinos 
  ON pagos.inquilino = inquilinos.idinquilinos

  • La función "CONCAT_WS" nos permite concatenar dos o más campos, indicando como primer parámetro el caracter de separación, en este caso el espacio en blanco (" ").
  • Podemos extraer la fecha de un DATETIME con la función YEAR.
  • Podemos extraer la hora de un DATETIME con la función TIME.
Ahora debemos asignar un "alias" a cada campo para tener un mejor orden:

SELECT 
  pagos.idpagos id,
  inquilinos.dni dni,
  CONCAT_WS(" ", inquilinos.nombres, inquilinos.paterno, inquilinos.materno) datos,
  pagos.monto monto
  DATE(pagos.fecha) fecha,
  TIME(pagos.fecha) hora
FROM pagos INNER JOIN inquilinos 
  ON pagos.inquilino = inquilinos.idinquilinos


Ahora podemos proceder a crear la vista anteponiendo lo siguiente: "CREATE VIEW ________ AS" de la siguiente manera

CREATE VIEW pagos_view AS
SELECT 
  pagos.idpagos id,
  inquilinos.dni dni,
  CONCAT_WS(" ", inquilinos.nombres, inquilinos.paterno, inquilinos.materno) datos,
  pagos.monto monto,
  DATE(pagos.fecha) fecha,
  TIME(pagos.fecha) hora
FROM pagos INNER JOIN inquilinos 
  ON pagos.inquilino = inquilinos.idinquilinos

  • El nombre de la vista es "pagos_view".
  • Podemos aplicarle consultas SELECT donde el nombre de los campos son los "alias" que le elegimos.

Probando

SELECT * FROM pagos_view;


Nos debe devolver algo así:

id dni datos monto fecha hora
1 31378082 LUISA PAUCAR NARRO 400.00 2019-10-21 21:34:35
2 43331042 AUGUSTO SOTOMAYOR NARVAJO 300.00 2019-10-18 18:30:00

Creando una tabla con clave foránea en MySQL

Diagrama EER

En este ejemplo vamos a implementar el código SQL para MySQL de la siguientes tablas que tenemos según el diagrama EER. Si quieres el código SQL de la tabla "inquilinos" has clic aquí


Código SQL

El código resultante será el siguiente:

CREATE TABLE IF NOT EXISTS pagos (
   idpagos INT NOT NULL AUTO_INCREMENT,
   inquilino INT NOT NULL,
   monto DECIMAL(10,2) NOT NULL,
   fecha DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (idpagos),
   CONSTRAINT fk_pago_inquilino
     FOREIGN KEY (inquilino)
     REFERENCES inquilinos (idinquilinos)
       ON DELETE NO ACTION
       ON UPDATE NO ACTION
)ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


  • El campo "inquilino" sera nuestra clave foránea, lo que significa que estará vinculado a la tabla "inquilinos", de tal manera que para agregar un pago, primero debemos tener por lo menos un inquilino, ya que el campo es "NOT NULL".
  • La clave "fk_pago_inquilino" es el nombre de la clave foránea debe ser única, lo que implica que no se podrá repetir este nombre en ningún campo o nombre de relación de esta base de datos.
  • Se usa las siguientes sentencias:
    • ON DELETE NO ACTION: Implica que si se desea eliminar un registro de "inquilinos" que tenga por lo menos un pago, saltará un error y no dejará borrarlo.
    • ON UPDATE NO ACTION: Implica que si se desea actualizar la clave primaria de un registro de "inquilinos" que tenga por lo menos un pago, saltará un error y no dejará cambiar la clave, pero ¿Por qué querríamos hacer eso?
  • ENGINE = InnoDB, nos garantiza que podremos utilizar claves foráneas y soporte del "commit" y "rollback"
  • DEFAULT CHARACTER SET = utf8; nos permite ingresar caracteres especiales como la "ñ" o vocales tildadas a nuestros registros.


Insertando datos de prueba

INSERT INTO pagos(inquilino, monto, fecha) 
   VALUES (1,400,CURRENT_TIMESTAMP),
          (2,300,"2019-10-18 18:30:00");

  • En el caso del campo "fecha", se emplea en el primer caso "CURRENT_TIMESTAMP" que devuelve la fecha y hora actual para el servidor MySQL, en el segundo caso se especifica la fecha y hora en el formato "YYYY-MM-DD HH:MM:SS".