GROUP BY with null values

1
SELECT s.producto,s.entrada AS entrada,r.salida AS salida,s.mes,s.anio  AS anio,s.entrada-r.salida AS total 
FROM (SELECT MONTH ( fecha ) AS mes,YEAR(fecha) AS anio,    producto,COALESCE(SUM(cantidad),0) AS entrada FROM eProductoTerminado 
WHERE ingresosalida='Ingreso' AND fecha BETWEEN '2015-01-01' AND  '2017-12-31' GROUP BY producto,anio ORDER BY producto) AS s
LEFT JOIN (SELECT MONTH ( fecha ) AS mes,YEAR(fecha) AS anio,producto,COALESCE(SUM(cantidad),0) AS salida FROM eProductoTerminado 
WHERE ingresosalida='Salida' AND fecha BETWEEN '2015-01-01' AND '2017-12-31'  GROUP BY producto,anio ORDER BY producto) AS r ON
s.producto=r.producto AND s.mes=r.mes AND s.anio=r.anio

I have this SQL statement, the problem with this statement is that in the WHERE income = output = 'Output' in the quantity field I have a NULL value and I have another value that has value, but by grouping the value + null (eye it is not a sum, it is a GROUP BY) in the result I take it as the NULL and not as the value, I already look for how to do it but it only comes out in the case of when a SUM is done.

It's MYSQL

    
asked by Rodrigo Loy 24.08.2016 в 20:38
source

2 answers

2

I recommend that you correctly format your code, this makes it easier to maintain and also allows users of the site to help you more quickly. Your formatted code would be the following:

SELECT  s.producto,
        s.entrada AS entrada,
        r.salida AS salida,
        s.mes,
        s.anio AS anio,
        s.entrada-r.salida AS total 
FROM (  SELECT  MONTH(fecha) AS mes,
                YEAR(fecha) AS anio,    
                producto,
                COALESCE(SUM(cantidad),0) AS entrada 
        FROM eProductoTerminado 
        WHERE ingresosalida = 'Ingreso' 
        AND fecha BETWEEN '2015-01-01' AND '2017-12-31' 
        GROUP BY producto,
                 anio 
        ORDER BY producto) AS s
LEFT JOIN ( SELECT  MONTH(fecha) AS mes,
                    YEAR(fecha) AS anio,
                    producto,
                    COALESCE(SUM(cantidad),0) AS salida 
            FROM eProductoTerminado 
            WHERE ingresosalida='Salida' 
            AND fecha BETWEEN '2015-01-01' AND '2017-12-31'  
            GROUP BY producto,
                     anio 
            ORDER BY producto) AS r 
    ON s.producto = r.producto 
    AND s.mes = r.mes 
    AND s.anio = r.anio

A couple of general recommendations: First of all, try to understand correctly how aggregations work in general, please do not trust the non-ANSI behavior of MySQL when using GROUP BY . It is always convenient to write explicitly all the columns that need to be in GROUP BY (they are all those that are not contained in any aggregation function).

Also, in your particular case, the LEFT JOIN with the subquery on the same table is completely unnecessary, you can use for example the expression CASE WHEN within the aggregation function.

In this way, your code can be rewritten like this:

SELECT  producto,
        COALESCE(SUM(CASE WHEN ingresosalida = 'Ingreso' THEN cantidad ELSE 0 END),0) AS entrada,
        COALESCE(SUM(CASE WHEN ingresosalida = 'Salida' THEN cantidad ELSE 0 END),0) AS salida,
        MONTH(fecha) AS mes,
        YEAR(fecha) AS anio,
        COALESCE(SUM(CASE WHEN ingresosalida = 'Ingreso' THEN 1 
                          WHEN ingresosalida = 'Salida' THEN -1 END * cantidad),0) AS total
FROM eProductoTerminado 
WHERE fecha BETWEEN '2015-01-01' AND '2017-12-31' 
GROUP BY producto,
         MONTH(fecha),
         YEAR(fecha);
    
answered by 24.08.2016 / 20:54
source
0

If there is a field in NULL in a row you will not add it, I recommend you, knowing that this field can be in NULL and it would not affect you to be 0, put IFNULL(campo, 0) . (thanks to the other comment this formatted, check the field you need)

SELECT  s.producto,
        s.entrada AS entrada,
        r.salida AS salida,
        s.mes,
        s.anio AS anio,
        s.entrada-r.salida AS total 
FROM (  SELECT  MONTH(fecha) AS mes,
                YEAR(fecha) AS anio,    
                producto,
                COALESCE(SUM(cantidad),0) AS entrada 
        FROM eProductoTerminado 
        WHERE ingresosalida = 'Ingreso' 
        AND fecha BETWEEN '2015-01-01' AND '2017-12-31' 
        GROUP BY producto,
                 anio 
        ORDER BY producto) AS s
LEFT JOIN ( SELECT  MONTH(fecha) AS mes,
                    YEAR(fecha) AS anio,
                    producto,
                    COALESCE(SUM(IFNULL(cantidad,0)),0) AS salida 
            FROM eProductoTerminado 
            WHERE ingresosalida='Salida' 
            AND fecha BETWEEN '2015-01-01' AND '2017-12-31'  
            GROUP BY producto,
                     anio 
            ORDER BY producto) AS r 
    ON s.producto = r.producto 
    AND s.mes = r.mes 
    AND s.anio = r.anio
    
answered by 26.07.2018 в 09:39