2010-05-27 7 views
12

tengo 2 tablas: miembros y comentarios. Selecciono todos los miembros y luego me uno a los comentarios. Pero en los comentarios, estoy seleccionando una SUMA de puntos, y si el usuario nunca comentó, no puedo obtener ese usuario en la lista ?!MySql seleccionando el valor predeterminado si no hay resultados?

Así cómo seleccionar el valor predeterminado de SUMA a ser 0 si el usuario nunca se ha comentado, o alguna otra solución:

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
      SUM(c.vote_value) AS vote_value, SUM(c.best) AS best, 
      SUM(c.vote_value) + SUM(c.best)*10 AS total 
      FROM members m 
      LEFT JOIN comments c ON m.member_id = c.author_id 
      GROUP BY c.author_id 
      ORDER BY m.member_id DESC 
      LIMIT 0, 20 

EDIT:

Voy a tratar de explicar .. Así que hay 2 tablas, miembros y comentarios. Necesito una lista de todos los usuarios con ranking. Los comentarios contienen todos los votos y las mejores respuestas.

Por lo tanto, necesito una lista de todos los usuarios, y ellos anotan.

miembros tabla:

member_id - username - avatar 

Comentarios mesa

comment_id - author_id - vote_value - best (0 OR 1) 

también trató de seleccionar entre comentarios y unirse a miembros, pero lo mismo otra vez :(

+0

¿Puede proporcionar algunos datos de ejemplo con un resultado esperado? No uso MySQL, así que tal vez tengan alguna sintaxis de acceso directo, pero están AGRANDANDO en una sola columna pero tienen varias columnas no agregadas en su SELECT –

+0

@Tom H .: MySQL realmente permite esta sintaxis: [GROUP BY y HAVING with Hidden Columns] (http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html). –

+0

Gracias Peter. Sabía que al menos uno de los principales RDBMS permitía eso, pero no podía recordar cuál. Sin embargo, dado que permite agrupaciones "ilógicas", podría dar como resultado datos "faltantes" porque "Al usar esta función, todas las filas de cada grupo deben tener los mismos valores para las columnas que se omiten de la parte GROUP BY. El servidor es gratuito para devolver cualquier valor del grupo, por lo que los resultados son indeterminados a menos que todos los valores sean los mismos ". c.comment_id puede no ser siempre el mismo para un c.author_id dado. –

Respuesta

18

No estoy seguro de por qué está incluyendo el comment_id en su lista SELECT si solo desea que los usuarios y sus clasificaciones. ¿Quieres solo su clasificación en ese comentario en particular? Voy a dar una solución para ahora que asume lo que desea es una lista de miembros completa con ranking:

SELECT 
    M.member_id, 
    M.user_id, 
    M.avatar, 
    COALESCE(SUM(C.vote_value), 0) AS vote_value_sum, 
    COALESCE(SUM(C.best), 0) AS best_sum, 
    COALESCE(SUM(C.vote_value), 0) + SUM(C.best) * 10 AS total_value 
FROM 
    Members M 
LEFT OUTER JOIN Comments C ON 
    C.author_id = M.member_id 
GROUP BY 
    M.member_id 
ORDER BY 
    total_value DESC 
LIMIT 0, 20 

(esto supone que vote_value y lo mejor NO son columnas NULL o que MySQL no tendrá en cuenta en el cálculo de los valores de suma - I creo que sí, pero no lo he probado)

-1

Usted podría utilizar la instrucción if para convertir NULL a 0

SELECT c.comment_id AS item_id, ... 
    IF(SUM(c.vote_value) is null, 0, SUM(c.vote_value)) as vote_value 
FROM members m 
LEFT JOIN comments c ON ... 
+1

COALESCE hace lo mismo, pero es más simple. SUM (COALESCE (c.vote_value, 0)) – nathan

+1

Ese es un mecanismo torpe para hacerlo. 'IF (x es NULL, y, x)' no es muy ordenado. –

+0

@nathan: no sabía eso antes pero solo tenía uso para eso. Gracias (por cierto, tuve que usar COALESCE (SUM (col), 0) porque a la inversa todavía se devolvió nulo. –

-1

usted podría tener un vistazo a la sentencia case, también: http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

En su caso el resultado sería similar a ...

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
     (CASE SUM(c.vote_value) WHEN NULL THEN 0 
     ELSE SUM(c.vote_value) END) AS vote_value, SUM(c.best) AS best, 
     (CASE SUM(c.vote_value) + SUM(c.najbolji)*10 WHEN null THEN 0 
     ELSE SUM(c.vote_value) + SUM(c.najbolji)*10 END) AS total 
     FROM members m 
     LEFT JOIN comments c ON m.member_id = c.author_id 
     GROUP BY c.author_id 
     ORDER BY m.member_id DESC 
     LIMIT 0, 20 
+0

Eso es extremadamente raro, desafortunadamente. –

18

MySQ L tiene un operador IFNULL que le permite devolver un valor distinto de null si el resultado es nulo.

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
      SUM(IFNULL(c.vote_value, 0)) AS vote_value, SUM(IFNULL(c.best, 0)) AS best, 
      SUM(IFNULL(c.vote_value, 0)) + SUM(IFNULL(c.best, 0))*10 AS total 
      FROM members m 
      LEFT JOIN comments c ON m.member_id = c.author_id 
      GROUP BY c.author_id 
      ORDER BY m.member_id DESC 
      LIMIT 0, 20 

Como mencionan otros, COALESCE hace algo similar (y también funciona en MySQL).

+0

Eso es probablemente un poco mejor que 'COALESCE 'por la circunstancia de querer un valor predeterminado. –

+0

También no todos los usuarios en el listado: \ – Kenan

+0

Entonces es muy probable que @nathan sea correcto. Intente agrupar en m.member_id en lugar de c.author_id para ver si eso ayuda. –

2

No creo que SUM sea el problema. Creo que puede ser su

GROUP BY c.author_id 

donde se está agrupando por el lado derecho de una combinación externa izquierda. No estoy seguro de lo que hace cuando el lado correcto no existe, pero supongo que eso no es lo que realmente quieres. Lo más probable es que se agrupe por algo en los miembros, no en los comentarios.

Habiendo dicho esto, sí, también debería usar COALESCE o IFNULL para convertir los valores nulos en 0.

+0

Intenté con la agrupación m.member_id pero igual, no todos los usuarios en el listado. Edité mi pregunta con estructuras de tabla, quizás ayude a entender mejor. Gracias – Kenan

+0

Trate de desglosar su consulta y reconstruirla para ver qué parte la rompe. Comience con solo "SELECCIONAR m.member_ id, SUM (c.vote_value) FROM ... "para asegurarse de que funciona, luego agregue las otras SUM y columnas de a una por vez para encontrar el problema. – nathan

Cuestiones relacionadas