Hacer ese cálculo, donde trabajas con dos canales de datos distintos (venta y entrega se relacionan, pero no componen la misma cadena de dependencias), implica realizar operaciones intermedias que no puedes juntar en una misma.
Cuando lo haces, cuando juntas indiscriminadamente una operación de venta con la entrega del material, terminas refiriéndote al mismo producto dos veces: Una vez cuando sumas la venta y otra cuando sumas la entrega... Por eso se produce un producto cartesiano.
Cuando trabajas en BBDD tienes que tener en cuenta la lógica de las dependencias, y la lista de productos entregados se relaciona con la lista de productos vendidos por sus cabeceras de definición (Venta y Entrega), no por sus detalles sumados.
Es un poco difícil de ver cuando no has estudiado algo de álgebra de Boole y de álgebra relacional.
La idea es que debes hacer las dos consultas
por separado en el from, y luego hacer el JOIN de los
resultados, no de las
tablas base:
Código MySQL:
Ver original p.id,
p.descripcion,
vendidos,
IFNULL(entregados
, 0) entregados
(SELECT P.ID
, SUM(DV.cant
) vendidos
, V.idcliente
(SELECT P.ID
, SUM(DE.cant
) entregados
, E.idcliente
GROUP BY P.ID
, E.idcliente
) T2
ON T1.ID
= T2.ID
AND T1.idcliente
= T2.idcliente
T1.idcliente = 'C-001';
Por otro lado, la tabla Cliente es innecesaria porque el ID que buscas ya se encuentra en las cabeceras, y esa tabla no agrega ni saca nada.