Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Ya estoy inscrito ¿Todavía no tienes acceso? Nuestros Planes
Solucionado (ver solución)
Solucionado
(ver solución)
2
respuestas

Hay DNIs en la tabla de facturas que no existen en la tabla de clientes

Esto lo descubrí porque al momento de ejecutar la consulta de la actividad 'Informe de ventas válidas #1':

SELECT 
    F.DNI AS DNI_CLIENTE,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA
FROM
    FACTURAS F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y')
ORDER BY;

Resulta en 546 registros.
Y al ejecutar la consulta de esta actividad ('Informe de ventas válidas #2'):

SELECT 

    /* Dado que, para el resultado de esta consulta, el campo TC.NOMBRE 
    tiene un único valor en todos los registros de cada agrupamiento, entonces no importa cuál
    escoja MySQL. Por lo tanto, y para evitar errores relacionados 
    con GROUP BY, se recomienda usar ANY_VALUE().
    Lo mismo se aplica para el campo TC.VOLUMEN_DE_COMPRA */
    
    ANY_VALUE(TC.NOMBRE) AS CLIENTE, 
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA,
    ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 AS VOLUMEN_DE_COMPRA,
    CASE
        WHEN SUM(IFA.CANTIDAD) < ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 THEN 'Sí'
        ELSE 'No'
    END AS `¿VENTA VÁLIDA?`
FROM
    FACTURAS F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
INNER JOIN 
    TABLA_DE_CLIENTES TC
ON
    F.DNI = TC.DNI
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y');

Resulta en 468 registros lo cual es inconsistente ya que debería devolver 546 registros (lo mismo que la primera consulta).
O sea, esta consulta es, en esencia, la misma que la primera pero con campos extra para hacer otro tipo de análisis (reporte).

Descubrí el porqué de esta inconsistencia y es que en la tabla de facturas hay DNIs que no existen en la tabla de clientes.

SELECT 
    DISTINCT F.DNI AS DNIs_FANTASMA 
FROM 
    FACTURAS F
WHERE NOT EXISTS(
    SELECT
        1
    FROM
        TABLA_DE_CLIENTES TC
    WHERE 
        F.DNI = TC.DNI);

Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad

SELECT 
    * 
FROM 
    TABLA_DE_CLIENTES 
WHERE 
    DNI IN('19290992743', '2600586709');

Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad
Por último, ¿Cuántos registros con esos DNIs fantasma hay en el resultado de la primera consulta?

SELECT
    COUNT(*) 
FROM (
    SELECT 
        F.DNI,
        DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
        SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA
    FROM
        FACTURAS F
    INNER JOIN
        ITEMS_FACTURAS IFA
    ON
        F.NUMERO = IFA.NUMERO
    WHERE 
        F.DNI IN('19290992743', '2600586709')
    GROUP BY
        F.DNI,
        DATE_FORMAT(F.FECHA_VENTA, '%m - %Y')) AS X;

El resultado es 78 lo cual es la resta de 546 - 468.
Y esto tiene sentido ya que al ejecutar la segunda consulta se hace un INNER JOIN el cual se rige por FACTURAS.DNI = TABLA_DE_CLIENTES DNI y es aquí donde esos 78 registros no se muestran.

Para solucionar esta inconsistencia hay dos opciones:

  1. Agregar clientes con esos DNIs fantasma a la tabla de clientes
  2. Borrar los registros de la tabla de facturas que tengan asociados esos DNIs fantasma
2 respuestas
solución!

Hola Yahadad, espero que estés bien

Entiendo tu situación y parece que has hecho un buen trabajo identificando el problema con los DNIs "fantasma". Como mencionaste, la diferencia en el número de registros entre las dos consultas se debe a que algunos DNIs en la tabla de "FACTURAS" no tienen un correspondiente en la tabla de "TABLA_DE_CLIENTES".

Para resolver esta inconsistencia, puedes considerar las dos opciones que mencionaste:

  1. Agregar los clientes faltantes a la tabla de clientes: Si estos DNIs son válidos y deberían existir en la tabla de clientes, entonces necesitas agregar esos registros. Esto asegurará que todas las facturas tengan un cliente asociado.

  2. Eliminar las facturas con DNIs que no existen en la tabla de clientes: Si esos DNIs no deberían estar en la tabla de facturas, puedes optar por eliminar esos registros. Esto limpiará tus datos y evitará problemas en futuros análisis.

Dependiendo de la integridad y el propósito de tus datos, una de estas soluciones será más adecuada. Si estás trabajando en un entorno de pruebas o aprendizaje, podrías experimentar con ambas para ver cómo afectan tus resultados.

Espero haber ayudado y buenos estudios!

Probé ambas soluciones:
Creé copias exactas de las tablas TABLA_DE_CLIENTES y FACTURAS y las nombré TABLA_DE_CLIENTES_COPIA Y FACTURAS_COPIA respectivamente.
Después agregué dos registros con esos DNIs 'fantasma' a la tabla TABLA_DE_CLIENTES_COPIA y eliminé los registros asociados con esos DNIs 'fantasma' de la tabla FACTURAS_COPIA:

CREATE TABLE
    FACTURAS_COPIA
LIKE
    FACTURAS;

INSERT INTO
    FACTURAS_COPIA
SELECT * FROM FACTURAS;

CREATE TABLE
    TABLA_DE_CLIENTES_COPIA
LIKE
    TABLA_DE_CLIENTES;

INSERT INTO
    TABLA_DE_CLIENTES_COPIA
SELECT * FROM TABLA_DE_CLIENTES;

DELETE FROM -- 12466 registros afectados
    FACTURAS_COPIA 
WHERE 
    DNI IN ('19290992743', '2600586709'); -- Los dos registros 'fantasma'

INSERT INTO TABLA_DE_CLIENTES_COPIA(DNI, NOMBRE, DIRECCION_1, BARRIO, CIUDAD, ESTADO, CP, FECHA_DE_NACIMIENTO, EDAD, SEXO, LIMITE_DE_CREDITO, VOLUMEN_DE_COMPRA, PRIMERA_COMPRA) VALUES
('19290992743', 'Fulanito','Avenida del panteón 15', 'San Juan', 'Teotihuacán', 'EM', '12345678', '2000-5-12', 25, 'M', 75000, 220000, 0),
('2600586709', 'Sutanito', 'Avenida del panteón 16', 'San Juan', 'Teotihuacán', 'EM', '12345678', '2000-5-12', 25, 'M', 170000, 95000, 1);

Ahora sí ya cuadra el número de filas resultante:

SELECT -- 546 registros
    F.DNI AS DNI_CLIENTE,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA
FROM
    FACTURAS F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y');
    
SELECT -- 546 registros
    ANY_VALUE(TC.NOMBRE) AS CLIENTE, 
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA,
    ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 AS VOLUMEN_DE_COMPRA,
    CASE
        WHEN SUM(IFA.CANTIDAD) < ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 THEN 'Sí'
        ELSE 'No'
    END AS `¿VENTA VÁLIDA?`
FROM
    FACTURAS F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
INNER JOIN 
    TABLA_DE_CLIENTES_COPIA TC
ON
    F.DNI = TC.DNI
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y');
SELECT -- 468 registros
    F.DNI AS DNI_CLIENTE,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA
FROM
    FACTURAS_COPIA F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y');

SELECT -- 468 registros
    ANY_VALUE(TC.NOMBRE) AS CLIENTE, 
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y') AS MES_AÑO,
    SUM(IFA.CANTIDAD) AS CANTIDAD_TOTAL_ADQUIRIDA,
    ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 AS VOLUMEN_DE_COMPRA,
    CASE
        WHEN SUM(IFA.CANTIDAD) < ANY_VALUE(TC.VOLUMEN_DE_COMPRA)/10 THEN 'Sí'
        ELSE 'No'
    END AS `¿VENTA VÁLIDA?`
FROM
    FACTURAS F
INNER JOIN
    ITEMS_FACTURAS IFA
ON
    F.NUMERO = IFA.NUMERO
INNER JOIN 
    TABLA_DE_CLIENTES TC
ON
    F.DNI = TC.DNI
GROUP BY
    F.DNI,
    DATE_FORMAT(F.FECHA_VENTA, '%m - %Y');