Diseño y Consultas SQL Esenciales para Gestión de Ferreterías
Clasificado en Informática
Escrito el en
español con un tamaño de 15,24 KB
Introducción al Esquema de Base de Datos para Ferreterías
Este documento presenta el diseño de una base de datos relacional para la gestión de una ferretería, incluyendo la definición de su esquema (DDL) y una serie de consultas SQL (DML) para la manipulación y recuperación de datos. El objetivo es proporcionar una estructura robusta para el almacenamiento de información sobre clientes, productos, proveedores, empleados y transacciones.
Configuración Inicial de la Base de Datos
Para comenzar, se crea la base de datos dbferreteria y se selecciona para su uso.
CREATE DATABASE dbferreteria;
GO
USE dbferreteria;
GODefinición de Tipos de Datos Personalizados
Se define un tipo de dato personalizado llamado codigo, que se utilizará para los identificadores principales y foráneos en las tablas, asegurando consistencia y no nulabilidad.
EXEC sp_addtype 'codigo', 'bigint', 'not null';
GOCreación de Tablas del Esquema
A continuación, se detallan las sentencias DDL para la creación de cada tabla, incluyendo sus columnas, tipos de datos, claves primarias y relaciones con otras tablas (claves foráneas).
Tabla: Zonas
Almacena información sobre las diferentes zonas geográficas.
CREATE TABLE zona(
idzona codigo PRIMARY KEY,
nombre_zona VARCHAR(50) NOT NULL
);
GOTabla: Barrios
Contiene los barrios, asociados a una zona específica.
CREATE TABLE barrio(
idbarrio codigo PRIMARY KEY,
nombre_barrio VARCHAR(70) NOT NULL,
idzona codigo REFERENCES zona(idzona)
);
GOTabla: Clientes
Tabla base para todos los clientes, sean naturales o empresas.
CREATE TABLE cliente(
id_cliente codigo PRIMARY KEY,
nit codigo,
telefono1 codigo,
telefono2 bigint,
telefono3 bigint,
correo VARCHAR(70) NOT NULL,
idbarrio codigo REFERENCES barrio(idbarrio)
);
GOTabla: Clientes Naturales
Detalles específicos para clientes que son personas naturales.
CREATE TABLE natural(
id_natural codigo PRIMARY KEY REFERENCES cliente(id_cliente),
nombre_cliente VARCHAR(70) NOT NULL,
app VARCHAR(70) NOT NULL,
apm VARCHAR(70) NOT NULL,
f_nac datetime NOT NULL,
f_def datetime,
sexo VARCHAR(1) NOT NULL
);
GOTabla: Clientes Empresa
Detalles específicos para clientes que son empresas.
CREATE TABLE empresa(
id_empresa codigo PRIMARY KEY REFERENCES cliente(id_cliente),
representante_legal VARCHAR(90)
);
GOTabla: Categorías de Productos
Clasificación principal de los productos.
CREATE TABLE categoria(
id_categoria codigo PRIMARY KEY,
nombre_categoria VARCHAR(70)
);
GOTabla: Subcategorías de Productos
Clasificación secundaria de los productos, dependiente de una categoría.
CREATE TABLE sub_categoria(
id_sub_categoria codigo PRIMARY KEY,
nombre_sub_categoria VARCHAR(70),
id_categoria codigo REFERENCES categoria(id_categoria)
);
GOTabla: Cargos de Empleados
Define los diferentes puestos de trabajo dentro de la ferretería.
CREATE TABLE cargo(
id_cargo codigo PRIMARY KEY,
nombre_cargo VARCHAR(70)
);
GOTabla: Empleados
Información detallada de los empleados.
CREATE TABLE empleado(
id_empleado codigo PRIMARY KEY,
nombre_empleado VARCHAR(70) NOT NULL,
app VARCHAR(70) NOT NULL,
apm VARCHAR(70) NOT NULL,
telefono1 bigint NOT NULL,
direccion VARCHAR(70) NOT NULL,
correo VARCHAR(70) NOT NULL,
id_cargo codigo REFERENCES cargo(id_cargo)
);
GOTabla: Pedidos de Clientes
Registra los pedidos realizados por los clientes.
CREATE TABLE pedido_cliente(
id_pedido codigo PRIMARY KEY,
fecha_pedido datetime NOT NULL,
id_cliente codigo REFERENCES cliente(id_cliente),
id_empleado codigo REFERENCES empleado(id_empleado)
);
GOTabla: Marcas de Productos
Información sobre las marcas de los productos.
CREATE TABLE marca(
id_marca codigo PRIMARY KEY,
nombre_marca VARCHAR(70) NOT NULL
);
GOTabla: Proveedores
Tabla base para todos los proveedores, sean naturales o empresas.
CREATE TABLE proveedor(
id_proveedor codigo PRIMARY KEY,
nit codigo,
direccion VARCHAR(70) NOT NULL,
telefono1 codigo,
telefono2 bigint,
correo VARCHAR(70) NOT NULL
);
GOTabla: Proveedores Naturales
Detalles específicos para proveedores que son personas naturales.
CREATE TABLE natural_proveedor(
id_proveedor codigo PRIMARY KEY REFERENCES proveedor(id_proveedor),
nombre_proveedor VARCHAR(70) NOT NULL,
app VARCHAR(70) NOT NULL,
apm VARCHAR(70) NOT NULL,
CI bigint NOT NULL
);
GOTabla: Proveedores Empresa
Detalles específicos para proveedores que son empresas.
CREATE TABLE empresa_proveedor(
id_proveedor codigo PRIMARY KEY REFERENCES proveedor(id_proveedor),
representante_legal VARCHAR(100) NOT NULL
);
GOTabla: Pedidos a Proveedores
Registra los pedidos realizados a los proveedores.
CREATE TABLE pedido_proveedor(
id_pedidoprov codigo PRIMARY KEY,
fecha_pedido datetime NOT NULL,
id_proveedor codigo REFERENCES proveedor(id_proveedor)
);
GOTabla: Productos
Información detallada de los productos disponibles en la ferretería.
CREATE TABLE producto(
id_producto codigo PRIMARY KEY,
nombre_producto VARCHAR(70) NOT NULL,
procedencia VARCHAR(70) NOT NULL,
peso decimal(18,2) NOT NULL,
stock bigint NOT NULL,
caracteristica VARCHAR(500),
id_marca codigo REFERENCES marca(id_marca),
id_subcategoria codigo REFERENCES sub_categoria(id_sub_categoria)
);
GOTabla: Detalle de Pedidos de Clientes
Contiene los productos y cantidades de cada pedido de cliente.
CREATE TABLE detalle_pedido(
id_pedido codigo REFERENCES pedido_cliente(id_pedido),
id_producto codigo REFERENCES producto(id_producto),
CONSTRAINT pk_detalle_pedido PRIMARY KEY(id_pedido,id_producto),
cantidad bigint NOT NULL,
precio_unitario decimal(18,2) NOT NULL
);
GOTabla: Detalle de Pedidos a Proveedores
Contiene los productos y cantidades de cada pedido a proveedor.
CREATE TABLE detalle_pedido_prove(
id_pedidoprov codigo REFERENCES pedido_proveedor(id_pedidoprov),
id_producto codigo REFERENCES producto(id_producto),
CONSTRAINT pk_detalle_pedido_prove PRIMARY KEY(id_pedidoprov,id_producto),
cantidad bigint NOT NULL,
precio_unitario decimal(18,2) NOT NULL
);
GOConsultas SQL para la Gestión de Datos
Esta sección presenta una serie de consultas SQL (DML) para extraer información relevante de la base de datos de la ferretería. Cada consulta está diseñada para responder a necesidades específicas de negocio.
Listado de Todas las Zonas
Obtiene todos los registros de la tabla
zona. Se muestran dos formas equivalentes de realizar esta consulta.SELECT * FROM zona; SELECT z.* FROM zona z;Listado de Clientes Naturales con Edad y NIT
Muestra el ID, nombre completo, NIT y la edad aproximada de cada cliente natural.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente, c.nit, DATEDIFF(d, n.f_nac, GETDATE())/365 AS edad FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural;Listado de Clientes Empresa con Representante Legal, NIT y Dirección
Obtiene el ID, representante legal, NIT, barrio y zona de los clientes que son empresas.
SELECT c.id_cliente, e.representante_legal AS Representante_Legal, c.nit AS NIT, b.nombre_barrio AS Barrio, z.nombre_zona AS Zona FROM cliente c INNER JOIN empresa e ON c.id_cliente = e.id_empresa INNER JOIN barrio b ON c.idbarrio = b.idbarrio INNER JOIN zona z ON b.idzona = z.idzona;Listado de Clientes Naturales Fallecidos
Identifica a los clientes naturales que tienen registrada una fecha de defunción.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural WHERE n.f_def IS NOT NULL;Listado de Clientes Naturales Vivos
Muestra los clientes naturales que no tienen registrada una fecha de defunción.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural WHERE n.f_def IS NULL;Clientes Naturales Mayores de 18 Años
Filtra los clientes naturales cuya edad calculada es igual o superior a 18 años.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS Nombre_Cliente, DATEDIFF(d, n.f_nac, GETDATE())/365 AS Edad FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural WHERE DATEDIFF(d, n.f_nac, GETDATE())/365 >= 18;Productos Cuyo Nombre Empieza con 'c' y Termina con 'a'
Busca productos cuyos nombres cumplen con un patrón específico.
SELECT p.* FROM producto p WHERE p.nombre_producto LIKE 'c%a';Proveedores Naturales Llamados 'Joaquin Perez'
Encuentra proveedores naturales con un nombre y apellido específicos.
SELECT p.id_proveedor, (n.nombre_proveedor + ' ' + n.app + ' ' + n.apm) AS Nombre_Proveedor, n.CI FROM proveedor p INNER JOIN natural_proveedor n ON p.id_proveedor = n.id_proveedor WHERE n.nombre_proveedor = 'Joaquin' AND n.app = 'Perez';Marcas Cuyo Nombre Empieza con 'tr' y Termina con 'a'
Filtra marcas que siguen un patrón de nombre determinado.
SELECT m.* FROM marca m WHERE m.nombre_marca LIKE 'tr%a';Empleados con Cargo entre ID 1 y 2
Selecciona empleados cuyo ID de cargo se encuentra en un rango específico.
SELECT e.* FROM empleado e WHERE e.id_cargo BETWEEN 1 AND 2;Productos con Nombres Específicos
Obtiene productos que coinciden con una lista predefinida de nombres.
SELECT p.* FROM producto p WHERE p.nombre_producto IN('cuchillo de mesa', 'pala honda', 'fierro de 2 pulgadas');Cantidad Total de Productos
Calcula el número total de productos registrados en la base de datos.
SELECT COUNT(p.id_producto) AS cantidad FROM producto p;Cliente Natural Más Adulto
Identifica al cliente natural con la mayor edad registrada.
SELECT TOP 1 c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS Nombre_Cliente, DATEDIFF(d, n.f_nac, GETDATE())/365 AS Edad FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural ORDER BY Edad DESC;Cliente Natural Más Joven
Identifica al cliente natural con la menor edad registrada.
SELECT TOP 1 c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS Nombre_Cliente, DATEDIFF(d, n.f_nac, GETDATE())/365 AS Edad FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural ORDER BY Edad ASC;Clientes Naturales que Compraron en Febrero (Año 2011)
Lista los clientes naturales que realizaron pedidos en el mes de febrero de 2011.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente_natural, p.id_pedido FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural INNER JOIN pedido_cliente p ON c.id_cliente = p.id_cliente WHERE p.fecha_pedido BETWEEN '2011-02-01' AND '2011-02-28';Clientes Empresa que Compraron en Mayo (Año 2011)
Lista los clientes empresa que realizaron pedidos en el mes de mayo de 2011.
SELECT c.id_cliente, e.representante_legal AS nombre_cliente_empresa, p.id_pedido FROM cliente c INNER JOIN empresa e ON c.id_cliente = e.id_empresa INNER JOIN pedido_cliente p ON c.id_cliente = p.id_cliente WHERE p.fecha_pedido BETWEEN '2011-05-01' AND '2011-05-31';Clientes Naturales Sin Pedidos (Uso de LEFT JOIN)
Encuentra clientes naturales que no han realizado ningún pedido.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente, p.id_pedido FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural LEFT JOIN pedido_cliente p ON c.id_cliente = p.id_cliente WHERE p.id_pedido IS NULL;Clientes Empresa Sin Pedidos (Uso de LEFT JOIN)
Encuentra clientes empresa que no han realizado ningún pedido.
SELECT c.id_cliente, e.representante_legal, c.nit, c.telefono1, p.id_pedido FROM cliente c INNER JOIN empresa e ON c.id_cliente = e.id_empresa LEFT JOIN pedido_cliente p ON c.id_cliente = p.id_cliente WHERE p.id_pedido IS NULL;Pedidos Sin Cliente Natural Asociado (Uso de RIGHT JOIN)
Identifica pedidos que no tienen un cliente natural asociado, posiblemente debido a datos inconsistentes o un tipo de cliente diferente.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente, p.id_pedido FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural RIGHT JOIN pedido_cliente p ON c.id_cliente = p.id_cliente WHERE c.id_cliente IS NULL;Código de Cliente, Nombre, Cantidad de Pedidos y Monto Total
Calcula el número de pedidos y el monto total gastado por cada cliente natural.
SELECT c.id_cliente, (n.nombre_cliente + ' ' + n.app + ' ' + n.apm) AS nombre_cliente, COUNT(p.id_pedido) AS cantidad_pedido, SUM(d.cantidad * d.precio_unitario) AS precio_total FROM cliente c INNER JOIN natural n ON c.id_cliente = n.id_natural INNER JOIN pedido_cliente p ON c.id_cliente = p.id_cliente INNER JOIN detalle_pedido d ON d.id_pedido = p.id_pedido GROUP BY c.id_cliente, n.nombre_cliente, n.app, n.apm;Empleados con Cargo 'Cajero'
Lista los empleados cuyo cargo es 'cajero'.
SELECT e.id_empleado, (e.nombre_empleado + ' ' + e.app + ' ' + e.apm) AS Nombre_Empleado, c.nombre_cargo FROM empleado e INNER JOIN cargo c ON e.id_cargo = c.id_cargo WHERE c.nombre_cargo IN('cajero');Proveedores Naturales Ordenados por CI (Ascendente)
Muestra los proveedores naturales ordenados por su número de identificación (CI) de menor a mayor.
SELECT p.id_proveedor, (n.nombre_proveedor + ' ' + n.app + ' ' + n.apm) AS Nombre_proveedor_natural, n.CI FROM proveedor p INNER JOIN natural_proveedor n ON p.id_proveedor = n.id_proveedor ORDER BY n.CI ASC;Proveedores Naturales Ordenados por CI (Descendente)
Muestra los proveedores naturales ordenados por su número de identificación (CI) de mayor a menor.
SELECT p.id_proveedor, (n.nombre_proveedor + ' ' + n.app + ' ' + n.apm) AS Nombre_proveedor_natural, n.CI FROM proveedor p INNER JOIN natural_proveedor n ON p.id_proveedor = n.id_proveedor ORDER BY n.CI DESC;Cantidad Total de Barrios
Calcula el número total de barrios registrados en la base de datos.
SELECT COUNT(b.idbarrio) AS Nro_de_Barrio FROM barrio b;