Contar campos null y no null, agrupando por otro campo

publicado por: Anonymous

Estoy construyendo un consulta que me diga la cantidad de campos que están nulos y la cantidad de campos que contengan algún contenido.

Datos. Esta es mi tabla:

CREATE TABLE opciones ( ID int(11) NOT NULL, 
                        id_pregunta int(50) DEFAULT NULL, 
                        idenc int(50) DEFAULT NULL, 
                        valor int(50) DEFAULT NULL, 
                        hallazgo varchar(250) COLLATE utf8mb4_spanish_ci DEFAULT NULL, 
                        Accion varchar(250) COLLATE utf8mb4_spanish_ci DEFAULT NULL, 
                        fecha date NOT NULL, hora date NOT NULL ) 
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; 


INSERT INTO opciones (ID, id_pregunta, idenc, valor, hallazgo, Accion, fecha, hora) 
      VALUES(73, 21, 16, 1, NULL, NULL, '0000-00-00', '0000-00-00'),
            (74, 22, 16, 1, NULL, NULL, '0000-00-00', '0000-00-00'),
            (75, 21, 16, 1, 'Se tiene un hallazgo? ', 'Cual es la acción correctiva ', '0000-00-00', '0000-00-00'),
            (76, 22, 16, 0, 'Se tiene un hallazgo? ', 'Cual es la acción correctiva ', '0000-00-00', '0000-00-00'),
            (77, 21, 16, 1, 'Se tiene un hallazgo? ', 'Cual es la acción correctiva ', '0000-00-00', '0000-00-00'), 

_x000D_

_x000D_

-- --------------------------------------------------------_x000D_
_x000D_
--_x000D_
-- Estructura de tabla para la tabla `respuestas`_x000D_
--_x000D_
_x000D_
CREATE TABLE `respuestas` (_x000D_
  `id` int(11) NOT NULL,_x000D_
  `texto` varchar(250) COLLATE utf8mb4_spanish_ci NOT NULL,_x000D_
  `idenc` int(11) NOT NULL_x000D_
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;_x000D_
_x000D_
--_x000D_
-- Volcado de datos para la tabla `respuestas`_x000D_
--_x000D_
_x000D_
INSERT INTO `respuestas` (`id`, `texto`, `idenc`) VALUES_x000D_
(31, 'El personal esta usando el EPP definido en el estÃ', 19),_x000D_
(32, 'sensores y/o guardas en funcionamiento?', 19),_x000D_
(33, 'señalamientos y salidas de emergencia estan en bu', 19),_x000D_
(34, 'las instrucciones de trabajo estan presentes y dis', 19),_x000D_
(35, 'la 1era pieza esta identificada y disponible en el', 19),_x000D_
(36, 'la hoja de mantenimiento autonomo esta actualizada', 19),_x000D_
(37, 'el operador realiza su operacion de acuerdo a la i', 19),_x000D_
(38, 'materiales identificados y en su caso segregados', 19),_x000D_
(39, 'registro de calidad realizados', 19),_x000D_
(40, 'hay registros de liberación de primera pieza', 19),_x000D_
(41, 'pieza master / muestras NG - OK disponibles', 19),_x000D_
(42, 'los indicadores estan posteados y actualizados', 19),_x000D_
(43, '', 19);_x000D_
_x000D_
--

_x000D_

_x000D_

_x000D_

Resultado esperado. Quiero obtener 2 campos por cada uno (uno con el total de null y el otro con el resto)

introducir la descripción de la imagen aquí

Quiero que me agrupe por id de pregunta, sumando la cantidad de null/no null por campo.

¿Qué intenté?

  1. Tengo lo siguiente, pero no me trae los campos null:

    SELECT a.texto as titulo, 
           SUM(CASE WHEN b.valor = 1 THEN 1 ELSE 0 END) AS "si", 
           SUM(CASE WHEN b.valor = 0 THEN 1 ELSE 0 END) AS "NO", 
           SUM( IF(b.hallazgo IS NOT NULL, 1, 0)), 
           SUM( IF(b.Accion IS NOT NULL, 1, 0)) 
           FROM respuestas a 
           INNER JOIN opciones b 
                 ON a.id = b.id_pregunta 
           WHERE a.idenc = 18 
           GROUP BY b.id_pregunta
    

    Solo me suma los campos pero no me separa por id. Actualmente me manda esto

    campo 1 = 3 accion 3 hallazgo
    campo 2 = 3 accion 3 hallazgo 
    campo 3 = 3 accion 3 hallazgo
    

    Pero quiero:

    campo 1 = 1 accion 1 hallazgo
    campo 2 = 0 accion 0 hallazgo 
    campo 3 = 2 accion 2 hallazgo
    
  2. Esta es la consulta que intenté luego:

    SELECT a.texto as titulo,b.id_pregunta,
    SUM(CASE WHEN b.valor = 1 THEN 1 ELSE 0 END) AS "si",
    SUM(CASE WHEN b.valor = 0 THEN 1 ELSE 0 END) AS "NO",
    SUM( IF(b.id_pregunta = a.id and b.hallazgo IS NOT NULL, 1, 0)) as hallazgos,
    SUM( IF(b.id_pregunta = a.id and b.Accion IS NOT NULL, 1, 0)) as acciones,
    SUM( IF(b.id_pregunta = a.id and b.hallazgo IS NULL, 1, 0)) as no hallazgos,
    SUM( IF(b.id_pregunta = a.id and b.Accion IS NULL, 1, 0)) as no acciones
    FROM respuestas a INNER JOIN opciones b ON a.id = b.id_pregunta WHERE a.idenc = 19
    GROUP BY a.id,a.texto,b.id_pregunta
    

    Este es el resultado que actualmente obtengo:

    introducir la descripción de la imagen aquí

Pregunta. ¿Cómo puedo obtener, para cada uno de los 2 campos (accion y hallazgo), la suma de los nulls en una columna y la suma de los no null en otra columna, agrupando por id_pregunta?

solución

Los valores de tipo NULL quieren decir “No tengo un valor definido” y se tratan
de una forma particular, en el siguiente ejemplo se muestra como contar:

USE test;

CREATE TABLE foo (
  id              BIGINT(20) NOT NULL AUTO_INCREMENT,
  attribute_name  CHAR(1),
  attribute_value CHAR(1),
  PRIMARY KEY (`id`)
);

INSERT INTO foo (attribute_name, attribute_value)
VALUES ('X', NULL),('Y', 'A'),('Y', 'B'),('Z', '');

Insertamos 4 registros, solo uno se considera NULL y los otros tres NOT NULL. Por último hacemos un SELECT agrupando por attribute_name y hacemos una especie de contador para los que son NULL y NOT NULL.

SELECT
  attribute_name,
  SUM(IF(attribute_value IS NULL, 1, 0)) AS 'Si',
  SUM(IF(attribute_value IS NOT NULL, 1, 0)) AS 'No'
FROM foo
GROUP BY attribute_name;
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *