Agrupar por no devolver 0 valor

Mi tabla contiene pk_id,reviewer_id,rating. Hay 4 tipos de calificación.

1-very good.
2-good.
3-bad.
4-very bad.

Quiero calcular la calificación otorgada por cada revisor. Significa: Si Akee con id 200 ha dado 2 calificaciones muy buenas, 4 buenas, 3 malas y cero muy malas a diferentes códigos.

quiero resultado

  count--- rate

   2---------1

   4---------2

   3---------3

   0---------4

Mi consulta es

SELECT COUNT(RATE),RATE
  FROM CODE_REVIEW WHERE CODE_REVIEWER_ID= 200
 GROUP BY RATE;

esta mostrando resultado

  count--- rate

   2---------1

   4---------2

   3---------3

Quiero mostrar la cuarta fila que es 4 calificación cero. ¿¿Cómo puede hacerse esto??

preguntado el 04 de julio de 12 a las 08:07

El Rate debe ser la clave principal de otra tabla? -

¿Tienes una tabla donde se definen las tarifas? -

Sugerencia: si no hay RATE=4 en la tabla CODE_REVIEW, ¿cómo sabe mysql que debe devolver la fila (0, 4)? -

no, no hay una tabla de mapeo para la tasa. ¿Se puede hacer de todos modos en el código detrás de la lógica? -

6 Respuestas

Si Tasa no es la clave principal en otra tabla, entonces necesita definir su propia lista de tasas para que MySQL sepa cuáles son las permutaciones de rate son:

SELECT  Rates.Rate,
        COUNT(Code_Review.Rate) AS CountOfRate
FROM    (   SELECT 1 AS Rate UNION ALL
            SELECT 2 AS Rate UNION ALL
            SELECT 3 AS Rate UNION ALL
            SELECT 4
        ) AS Rates
        LEFT JOIN Code_Review
            ON Code_Review.Rate = Rates.Rate
            AND CODE_REVIEWER_ID = 200
GROUP BY Rates.Rate

Respondido 04 Jul 12, 09:07

Esto no funcionará. COUNT(*) simplemente cuenta la existencia de una fila. Ya que 4 existe como fila en la primera subselección, el conteo siempre será >= 1 aunque el usuario nunca haya votado 4. Lo que debes hacer es que cuente en una de las columnas del LEFT JOIN'ed tabla desde NULLs no se tienen en cuenta en el COUNT() total. - Zane Bien

Prueba esta consulta:

SELECT coalesce(c.cnt, 0), r.rate
  FROM (SELECT 1 AS rate UNION ALL SELECT 2
        UNION ALL SELECT 3 UNION ALL SELECT 4) AS r
  LEFT JOIN (SELECT COUNT(RATE),RATE
          FROM CODE_REVIEW WHERE CODE_REVIEWER_ID= 200
         GROUP BY RATE) AS c
    ON r.rate = c.rate;
  1. La primera subconsulta crea una lista de tarifas posibles. Puede evitarlo si tiene una tabla que define todas las tarifas;
  2. La segunda subconsulta es suya;
  3. LEFT JOIN garantiza que se mostrarán todas las tarifas;
  4. coalesce() se necesita para convertir NULL en 0.

Respondido 04 Jul 12, 08:07

Suponiendo que no tiene una tabla separada donde se definen las tarifas.

SElECT * from (
  SELECT distinct(m.rate), countrate from code_review m 
  LEFT JOIN
  (SELECT COUNT(rate) as countrate,rate FROM code_review 
     WHERE code_reviewer_id=200 GROUP BY rate) t 
  ON m.rate=t.rate) a

Respondido 04 Jul 12, 08:07

Solo FYI: DISTINCT no es una función, se aplica a toda la fila. Encerrar la columna junto a DISTINCT entre paréntesis no cambia ese hecho. - andriy m

Podrías hacerlo algo como esto

SELECT
            rates.RATE
            , SUM(COUNT) COUNT
   FROM
           (
           SELECT 1 RATE, 0 COUNT UNION ALL
           SELECT 2 RATE, 0 COUNT UNION ALL
           SELECT 3 RATE, 0 COUNT UNION ALL
           SELECT 4 RATE, 0 COUNT
           ) Rates
       LEFT JOIN
           (
               SELECT
                         RATE
                       , COUNT(RATE) COUNT 
                   FROM
                       CODE_REVIEW 
                   WHERE
                       CODE_REVIEWER_ID= 200
                   GROUP BY RATE
           ) Ratings200
           ON Ratings200.RATE = Rates.RATE

Respondido 04 Jul 12, 08:07

Si puede, debe presionar para intentar obtenerlo en formato de columna, ya que es tan simple como:

SELECT
    SUM(rate = 1) AS 1,
    SUM(rate = 2) AS 2,
    SUM(rate = 3) AS 3,
    SUM(rate = 4) AS 4
FROM
    code_review
WHERE
    code_reviewer_id = 200

Pero si realmente necesita un formato de fila, podría hacerlo:

SELECT
    a.rate,
    COUNT(b.rate) AS cnt
FROM
    (
        SELECT 1 AS rate UNION ALL
        SELECT 2 AS rate UNION ALL
        SELECT 3 AS rate UNION ALL
        SELECT 4 AS rate
    ) a
LEFT JOIN
    code_review b ON a.rate = b.rate AND code_reviewer_id = 200
GROUP BY
    a.rate

Respondido 04 Jul 12, 10:07

SELECT 
    Rate,
    totCount
FROM 
(
    Select
        Rate,
        count(Rate) as totCount
    from
        Code_Review 
    where 
        CODE_REVIEWER_ID  = 200  
    group by 
        Rate
    union
    select  4, 0  
    union
    select  3, 0  
    union
    select  2, 0  
    union
    select  1, 0 
) AS T 
group by  
    T.Rate

Respondido 07 Jul 12, 08:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.