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

miércoles, 2 de septiembre de 2026

Consultas entre dos o más tablas en SQL Server

SQL Server utiliza uniones para recuperar datos de varias tablas basándose en las relaciones lógicas entre ellas. Las combinaciones son fundamentales para las operaciones de bases de datos relacionales y permiten combinar datos de dos o más tablas en un único conjunto de resultados.

SQL Server implementa tanto operaciones de unión lógica (definidas por la sintaxis de Transact-SQL) como operaciones de unión física (los algoritmos que se utilizan para ejecutar las uniones). Comprender ambos aspectos ayuda a escribir consultas eficientes y a optimizar el rendimiento de la base de datos.

Las uniones indican la forma en la que SQL Server debe usar los datos de una tabla para seleccionar las filas de otra. 

Una condición de unión define cómo se relacionan dos tablas en una consulta mediante:
  • La especificación de la columna de cada tabla que se utilizará para la unión. Una condición de unión típica especifica una clave foránea de una tabla y su clave asociada en la otra.
  • La especificación de un operador lógico (por ejemplo, = o <>,) que se utilizará para comparar los valores de las columnas.
Las uniones se expresan lógicamente mediante la siguiente sintaxis de Transact-SQL:
  • INNER JOIN 
  • LEFT JOIN 
  • RIGHT JOIN 
  • FULL  JOIN 
En la unión de tipo Inner Join se obtienen los datos que son comunes a 2 o más tablas en las que se realiza la consulta. Left Join devuelve todos los registros de la tabla izquierda y también los que coinciden con los registros de la tabla de la derecha (La tabla de la izquierda es la primer tabla que se define en la consulta de SQL, la de la derecha es la segunda tabla que se define en la consulta), además, si no hay coincidencia entre ambas tablas no se devuelven resultados de registros. Right join es el caso contrario, devuelve todos los registros de la tabla derecha y también los que coinciden con los registros de la tabla de la izquierda. Full Join devuelve todos los registros de las tablas, los de la tabla izquierda, los de la derecha y los que coinciden en ambas tablas.

De manera visual la uniones se muestran en la siguiente imagen.




Ejemplos
Se puede usar el siguiente código para ejemplificar el uso de INNER JOIN.

CREATE TABLE clientes ( 
idcliente int NOT NULL primary key,
nombre varchar(20) NOT NULL,
apellido varchar(30) NOT NULL,
direccion varchar(100) NOT NULL,
ciudad varchar(50) NOT NULL,
telefono numeric(10) NULL,
);

CREATE TABLE ordenes(
id_orden int NOT NULL primary key,
idcliente int foreign key references clientes(idcliente),
fecha_orden date default getdate(),
id_vendedor int NOT NULL
);

SELECT ordenes.id_orden, Clientes.nombre, Clientes.apellido, ordenes.fecha_orden -- De
la tabla ordenes elige el id de la orden, de la tabla de clientes el nombre y el
apellido y de la tabla de ordenes la fecha
FROM ordenes -- Para esto, usa la tabla de ordenes
INNER JOIN Clientes on ordenes.idcliente = Clientes.idCliente; -- y por medio un inner
JOIN con la tabla Clientes trae esos campos CUANDO el id del cliente de la tabla de
ordenes sea el mismo id del cliente en la tabla de Clientes

SELECT ordenes.id_orden, Clientes.nombre, Clientes.apellido, ordenes.fecha_orden,
ordenes.id_vendedor -- También podemos traer el id del vendedor para saber quien le ha
vendido productos al cliente Juan
FROM ordenes
INNER JOIN Clientes ON ordenes.idcliente = Clientes.idCliente
WHERE nombre = 'Juan' ORDER BY fecha_orden; -- Realizamos la misma consulta anterior
pero filtrando para el cliente con nombre Juan y ordenamos por fecha

Este código se puede ver de otra manera: Se toma cada registro de la tabla de ordenes y se checa con qué cliente está asociado esa orden por medio del id del cliente, después de esta verificación se van a devolver el nombre y el apellido en la tabla de clientes pero también el id de la orden y la fecha de la orden en la tabla de ordenes, estos campos se devuelven para cada uno de los registros de la tabla de ordenes.

Si se desea saber cuáles clientes tienen ordenes de servicio y cuáles no las tienen, se puede hacer uso de left join porque de esta manera podemos obtener aquellos registros que están relacionados con la tabla de ordenes pero también aquellos que no están relacionados, esto cumple con la definición de left join que devuelve los propios registros de la tabla izquierda y también sus coincidencias con respecto a otra tabla con la que está relacionada.

El siguiente ejemplo de código muestra cómo se puede usar left join para solucionar el problema previamente explicado.

SELECT Clientes.nombre, Clientes.apellido, ordenes.id_orden, ordenes.fecha_orden -- Devuelve el nombre y el apellido de la tabla Clientes y el id de orden y la fecha de
la tabla de ordenes
FROM Clientes --(Clientes es la tabla de la izquierda o primer tabla) Para esto, usa la tabla de ordenes
LEFT JOIN ordenes on Clientes.idcliente = ordenes.idcliente -- y por medio un left join con la tabla ordenes trae esos campos CUANDO el id del cliente de la tabla de ordenes sea el mismo id del cliente en la tabla de Clientes
order by id_orden; -- ordena la consulta por el id de la orden

SELECT cli.nombre, cli.apellido, ord.id_orden, ord.fecha_orden
FROM Clientes cli -- La tabla Clientes usa 'cli' como alias
LEFT JOIN ordenes ord on cli.idcliente = ord.idcliente -- La tabla ordenes usa 'ord' como alias
order by id_orden;

Referencias
Para obtener más información sobre las uniones, consultar el siguiente enlace.


miércoles, 3 de septiembre de 2025

Modularización de consultas por medio de procedimientos almacenados en SQL Server

En SQL Server un procedimiento almacenado es un grupo de una o más instrucciones de Transact-SQL (Lenguaje de programación). Estos procedimientos aceptan parámetros de entrada y devuelven múltiples valores en forma de parámetros de salida al programa que llama al procedimiento, además contienen instrucciones de programación que realizan operaciones en la base de datos. También, estos procedimientos devuelven un valor de estado al programa que llamo al procedimiento para indicar éxito o fracaso (y el motivo del fracaso).

Gracias al control de flujo que ofrece SQL Server es que podemos usar los procedimientos almacenados. Como se describió, Transact-SQL tiene diversas instrucciones que nos permiten emplear estructuras de control tal como en los lenguajes de programación, es decir, podemos usar construcciones del lenguaje para modificar el flujo de ejecución de las instrucciones de un programa.

Los procedimientos almacenados tienen la ventaja de que permiten modularizar soluciones de software al encapsular el código en unidades manejables y con ello facilitar su reutilización. Además, con el uso de procedimientos almacenados los comandos de estos se ejecutan como un único lote de código, esto puede reducir significativamente el tráfico de red entre el servidor y el cliente, ya que solo se envía la llamada a través de la red para ejecutar un procedimiento determinado. Sin la encapsulación de código que proporciona un procedimiento, cada línea de código tendría que atravesar la red.

Creación de procedimientos almacenados
La sentencia CREATE PROCEDURE es la que nos permite la creación y persistencia de bloques de código, además, cuando se usa esta sentencia, el procedimiento se guarda en la carpeta Databases > NombreBaseDeDatos > Programmability > Stored procedures, aquí es donde podemos encontrar todos los bloques de código que se han guardado en la propia base de datos. La carpeta de procedimientos almacenados se muestra en la siguiente imagen.


Como ejemplo de código, vamos a suponer que tenemos una tabla de productos que tiene un campo cantidad y que deseamos actualizar los valores de este campo, para esto, podemos crear un procedimiento almacenado que nos va permitir llamarlo cada vez que lo necesitemos sin tener que volver a escribir el código en su interior. El código es el que se muestra en seguida.

CREATE PROCEDURE p_actualiza_stock
AS
BEGIN
    IF EXISTS(SELECT * FROM productos
            WHERE cantidad = 0)
        UPDATE 
            productos SET cantidad = 20
        WHERE 
            cantidad <= 5;
END

Con el código anterior se guarda el procedimiento y ahora solo falta ejecutarlo por medio de la sentencia EXEC, esto se muestra a continuación.

EXECUTE p_actualiza_stock;

Es importante mencionar que cada vez que un procedimiento se guarda y modifica en la base de datos, será necesario ejecutarlo o mandarlo a llamar por medio de la sentencia EXEC.

Actualización de procedimientos almacenados
Para actualizar o modificar un procedimiento que ya guardamos previamente, tenemos que usar la sentencia ALTER PROCEDURE. Como ejemplo, podemos modificar el procedimiento que describimos previamente, en este caso podemos agregar 10 unidades más a cada artículo que tenga 20 elementos, entonces el código es el siguiente.

ALTER PROCEDURE p_actualiza_stock
AS
BEGIN
    IF EXISTS(SELECT * FROM productos
            WHERE cantidad = 10)
        UPDATE 
            productos SET cantidad = 30
        WHERE 
            cantidad = 20;
END

De igual manera, la instrucción ALTER modifica y guarda el procedimiento en la base de datos en cuestión.

Borrar procedimientos almacenados
Para borrar procedimientos almacenados tenemos que usar la instrucción DROP PROCEDURE, entonces para borrar el procedimiento con el que hemos estado trabajando tenemos que usar el código que muestra a continuación.

DROP PROCEDURE p_actualiza_stock;

Con esto, el módulo de actualización de stock ya no estará disponible en la carpeta Stored Procedures de la base de datos.

Parámetros de entrada en procedimientos almacenados
Para usar parámetros o variables al interior de una procedimiento almacenado tenemos que declarar las variables antes del propio código de ejecución, es decir, antes de la clausula AS, recordemos que la declaración de variables tiene la sintaxis @nombreVar TipoDeDato = valor, además, si se usan varias variables tenemos que separarlas por comas. En el siguiente ejemplo se muestra un procedimiento almacenado que nos permite buscar un producto con determinados valores en cada campo. En este caso la tabla de productos tiene los campos nombre, precio y cantidad (existencia) en su estructura.

CREATE OR ALTER PROCEDURE p_buscar_producto
@producto VARCHAR(40) = 'Microcontrolador',
@precioProducto SMALLMONEY = 29.99,
@existencia INT = 35
AS
SELECT * FROM productos
WHERE
    nombre = @producto AND
    precio = @precioProducto AND
    cantidad = @existencia;

En esta ocasión se uso la palabra reservada ALTER en el encabezado del procedimiento almacenado, con esto podemos crear y/o modificar un procedimiento en el mismo lugar sin la necesidad de realizar estas operaciones por separado.

Referencias
En los siguientes enlaces se puede obtener más detalles técnicos sobre las sentencias de código usadas en este artículo.