# SQL: Estructuras de Control y Consultas Básicas

***

> Este es el flujo estándar para construir una consulta SQL.
>
> SELECT> \
> FROM> \
> WHERE> \
> GROUP BY> \
> HAVING> \
> ORDER BY> \
> LIMIT/TOP

#### **1. Estructura CASE:**

La estructura `CASE` es útil para realizar decisiones dentro de una consulta SQL, permitiendo evaluar diferentes condiciones. A continuación se muestra el ejemplo básico:

```sql
-- Estructura CASE básica:
Begin 
    Declare @v_nroMensaje Tinyint =1
    Declare @v_txtMensaje varchar(max)
    Set @v_txtMensaje = case @v_nroMensaje
        when 1 then 'Hello world'
        when 2 then 'vas a lograrlo'
        when 3 then 'Eres un campeon'
        else 'Mensaje no implementado'
    End
    print 'El valor es: ' + @v_txtMensaje
End
go
```

#### **2. Evaluación de Regiones con CASE:**

Este bloque de código utiliza el `CASE` para evaluar regiones y asignar un valor según la región de origen.

```sql
-- Utilizar el bloque CASE para evaluar lo siguiente:
-- Si eres de Lima: Te corresponde 30
-- Si eres de Tumbes: Te corresponde 20
-- Si eres de Ica: Te corresponde 10
-- Caso contrario: Región incorrecta
Begin
    DECLARE @region VARCHAR(max) = 'Ica'
    DECLARE @valorAsignado VARCHAR(MAX)
    SET @valorAsignado = CASE @region
        WHEN 'Lima' THEN '30'
        WHEN 'Tumbes' THEN '20'
        WHEN 'Ica' THEN '10'
        ELSE 'Región incorrecta'
    END
    PRINT 'El valor es: ' + @valorAsignado
End
go
```

***

#### **3. Funciones de Fecha y Tiempo:**

Consultas relacionadas con fechas y cálculos de diferencia entre fechas.

```sql
-- Obtener fecha y hora actual
select getdate(); 

-- Obtener diferencia de años entre una fecha y la actual
select DATEDIFF(YY,'09/07/2004',getdate()) -- Puede usar YY, MM, DD, SS, QQ
```

***

#### **4. Promedio de Edad de Empleados:**

Consulta para obtener el promedio de edad de los empleados en una empresa.

```sql
select AVG(DATEDIFF(YY,BirthDate,getdate())) AS TOTAL
from Employees; -- Intervalos de tiempo (YY, MM, etc.) con AVG para obtener un promedio
```

***

#### **5. Estructura CASE - Evaluación de Edad:**

El siguiente bloque de código usa `CASE` para determinar la etapa generacional según la edad.

```sql
Begin
    set Dateformat DMY
    Declare @v_fna DATE = '10/10/2000'
    DECLARE @v_edad int = DATEDIFF(yy,@v_fna,GETDATE())
    DECLARE @v_etapa varchar(60) = case
        When @v_edad < 65 Then 'Adulto mayor'
        When @v_edad <= 18 Then 'Mayor de edad'
        When @v_edad <= 17 Then 'Menor de edad'
        Else 'No corresponde la edad'
    End
    Print 'La etapa generacional es: ' + @v_etapa
End
go
```

***

#### **6. Optimización de Consultas con CASE:**

En este caso, el `CASE` se utiliza para optimizar la consulta de estado de una factura.

```sql
-- Optimizando con CASE
select NUM_FAC,FEC_FAC,EST_FAC,
    CASE EST_FAC
        when 2 then 'Cancelado'
        when 3 then 'Pendiente'
        else 'No corresponde'
    End As 'Estado de la factura' 
from TB_FACTURA
go
```

***

#### **7. Utilización de WHILE:**

El ciclo `WHILE` permite ejecutar un bloque de código repetidamente mientras se cumpla una condición.

```sql
DECLARE @NOTA INT = 10
WHILE(@NOTA <= 13)
    BEGIN
        PRINT 'DESAPROBADO'
        SET @NOTA =@NOTA +1
    END
GO
```

***

#### **8. Ejemplo de Multiplicación con WHILE:**

Mostrar los productos de multiplicar números del 1 al 10 por 4.

```sql
DECLARE @NUMERO INT = 1;
WHILE(@NUMERO <= 10)
    BEGIN
        PRINT CAST(@NUMERO AS VARCHAR) + ' x 4 = ' + CAST(@NUMERO * 4 AS VARCHAR)
        SET @NUMERO = @NUMERO +1
    END
GO
```

***

#### **9. Función DATEADD:**

Se puede utilizar para sumar intervalos de tiempo (meses, días, etc.) a una fecha específica.

```sql
select DATEADD(MM,1,'01/01/2025') 

Begin
    Set DateFormat DMY
    Declare @v_fechainicial Date='01/01/2025'
    Declare @v_fechaFinal Date= GETDATE()
    While @v_fechainicial <= @v_fechaFinal
    Begin
        Print @v_fechainicial
        Set @v_fechainicial=DateAdd (MM,2,@v_fechainicial)
    End
End
go
```

***

#### **10. Ejemplos de Consultas:**

**10.1. Listado de Precios de Productos:**

Obtener la suma total de los precios de los productos.

```sql
SELECT SUM(PRE_PRO) AS 'SUMA TOTAL' FROM TB_PRODUCTO;
```

**10.2. Maximo y Minimo Sueldo de Vendedores:**

Obtener el sueldo máximo y mínimo de los vendedores de tipo "1".

```sql
SELECT MAX(SUELDO_VEN) AS MAXIMO, MIN(SUELDO_VEN) AS MINIMO FROM TB_VENDEDOR
WHERE TIP_VEN = 1;
```

**10.3. Promedio de Antigüedad de los Clientes:**

Obtener el promedio de antigüedad de los clientes.

```sql
Select AVG(DATEDIFF(YY,FEC_REG,GETDATE())) AS PROMEDIO from TB_CLIENTE
```

**10.4. Facturas Pendientes:**

Contar la cantidad de facturas pendientes.

```sql
SELECT COUNT(EST_FAC) AS ESTADO FROM TB_FACTURA WHERE EST_FAC = 2;
```

**10.5. Producto Más Caro:**

Obtener el nombre y el precio del producto más caro.

```sql
SELECT DES_PRO, PRE_PRO FROM TB_PRODUCTO WHERE PRE_PRO = (SELECT MAX(PRE_PRO) FROM TB_PRODUCTO);
```

***

#### **11. Consultas con GROUP BY:**

**11.1. Agrupar Clientes por Distrito:**

Agrupar los clientes según el código del distrito.

```sql
SELECT COD_DIS, COUNT(*) AS CONTADOR FROM TB_CLIENTE GROUP BY COD_DIS;
```

**11.2. Agrupar Productos por Línea de Producto:**

Agrupar productos por línea de producto con cantidad >= 10.

```sql
SELECT LIN_PRO, COUNT(*) AS TOTAL FROM TB_PRODUCTO GROUP BY LIN_PRO HAVING COUNT(*) >= 10 ORDER BY COUNT(*) DESC;
```

**11.3. Clientes por Tipo de Cliente:**

Agrupar clientes por tipo de cliente con cantidad >= 10.

```sql
SELECT TIP_CLI, COUNT(*) AS CANTIDAD FROM TB_CLIENTE GROUP BY TIP_CLI HAVING COUNT(*) >= 10;
```

***

#### **12. Consultas con JOIN (Multitablas):**

<figure><img src="https://2388471899-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FT7EGcEJYcU0fHj1mL1yx%2Fuploads%2Fv2fXmNNmbKE0cMKAyepd%2Fimage.png?alt=media&#x26;token=ca491cfd-bd8b-4f94-8f49-4d17628bc8a7" alt=""><figcaption></figcaption></figure>

**12.1. Nombre de Vendedor y Distrito:**

Mostrar el nombre del vendedor junto con el nombre del distrito.

```sql
-- DOBLE INTER JOIN -> UNA TABLA QUE RELACIONA A AMBAS...
-- PUEDE A VER MUCHOS JOIN PERO GENERA MUCHOS DATOS REPETITVOS...

SELECT TB_VENDEDOR.NOM_VEN, TB_DISTRITO.NOM_DIS FROM TB_VENDEDOR JOIN TB_DISTRITO ON TB_VENDEDOR.COD_DIS = TB_DISTRITO.COD_DIS
ORDER BY NOM_DIS;
```

**12.2. Facturas Generadas por Cliente:**

Contar la cantidad de facturas generadas por cliente.

```sql
SELECT c.CONTACTO, COUNT(*) AS [Cantidad de facturas] 
FROM TB_CLIENTE c 
INNER JOIN TB_FACTURA f 
ON (c.COD_CLI = f.COD_CLI) 
GROUP BY c.CONTACTO;
```

**12.3. Producto y Proveedor:**

Mostrar el nombre del producto y el nombre del proveedor.

```sql
SELECT TB_PROVEEDOR.RAZ_SOC_PRV, TB_PRODUCTO.DES_PRO FROM TB_PROVEEDOR JOIN TB_ABASTECIMIENTO
ON TB_PROVEEDOR.COD_PRV = TB_ABASTECIMIENTO.COD_PRV
JOIN TB_PRODUCTO ON TB_ABASTECIMIENTO.COD_PRO = TB_PRODUCTO.COD_PRO
WHERE RAZ_SOC_PRV = 'Faber Castell';
```

***

#### **13. Consultas con TOP:**

**13.1. Primeros 3 Productos:**

Obtener los 3 productos más caros.

```sql
SELECT TOP 3 PRE_PRO FROM TB_PRODUCTO;
```

**13.2. Últimos 3 Productos:**

Obtener los 3 productos más baratos.

```sql
SELECT TOP 3 PRE_PRO FROM TB_PRODUCTO ORDER BY PRE_PRO DESC;
```
