2012-03-09 4 views
5

lo tanto, pensé que estaba haciendo bastante bien en MySQL hasta que me encontré con esta idea:Seleccionar usuarios que han downvoted pero nunca upvoted

que tienen un registro de tabla "útiles" (bien llamado votes) con estos campos:

  • id: ID único del voto
  • user: ID de usuario único de la persona que votó
  • item: Identificación del elemento que está votando en
  • vote: El voto que fundido conjunto ('arriba', 'abajo')

Ahora, estoy tratando de encontrar una forma de SQL para encontrar usuarios cuyos únicos votos son votos a favor. Sé de una forma de escribirlo procesalmente en PHP después de consultar la mayoría de los datos fuera de la tabla, pero parece realmente, muy ineficiente hacer eso cuando solo unas pocas consultas pueden descubrirlo.

Idealmente quiero que mi resultado sea solo una lista de usuarios que tienen 0 votos ascendentes (porque estar en la mesa significa que votaron, por lo que solo votan negativamente) y tal vez el número de votos negativos que emitieron.

¿Alguna idea sobre cómo debo abordar esto?

+2

posible duplicado de [Al menos un X pero sin Ys de consulta] (http://stackoverflow.com/questions/9626965/atleast-one-x-but-no- ys-query) –

+0

Oh wow, eso es muy similar, lindo! – Tim

+0

Dejé un comentario sobre la otra pregunta (que creo que tiene una buena respuesta y fue un poco anterior) que necesita un título mejor, más amigable con el SEO. No sé lo que sería, per se, pero no creo * [Al menos una X pero no Ys Query] (http://stackoverflow.com/questions/9626965/at-least-one-x -but-no-ys-query) * funciona bastante bien para describir lo que significa. –

Respuesta

5
SELECT user, SUM(IF(vote='down',1,0)) AS numDownVotes 
FROM votes 
GROUP BY user 
HAVING SUM(IF(vote='up',1,0))=0 -- 0 upvotes 
    AND SUM(IF(vote='down',1,0))>0 -- at least 1 downvotes 

no puedo evitar sentir que hay una ordenada GROUP BY user, vote manera de hacer esto aunque.

+0

La salida es exactamente lo que estaba buscando. – Tim

+0

Eso es bastante ingenioso, y evita el "problema" de no poder hacer coincidir "DÓNDE" con un "ALIAS" para una subconsulta. –

3
select user, count(user) 
from votes 
where user not in (
    select distinct user 
    from votes 
    where votes = 'up') 
+0

Esto cuenta el número de downvotes que cada usuario ha dado; pero si un usuario tiene downvoted y upvoted, todavía los incluirá (y su total de votos negativos). –

+0

@ mathematical.coffee: tienes razón. Fijo. – Dinah

+0

Esto está cerca, pero el conteo (usuario) está dando el valor incorrecto (en este caso, 20 en lugar de 2.) – Tim

3

No he comprobado la sintaxis o cualquier cosa, pero esto viene a la mente ...

SELECT user 
FROM votes 
GROUP BY user 
    HAVING SUM(IF(vote = 'up', 1, 0)) = 0 
    AND SUM(IF(vote = 'down', 1, 0)) > 0 
+0

Esto parece muy prometedor, pero ¿hay alguna forma de identificar exactamente cuántos downvotes ha emitido cada usuario? – Tim

+0

Claro, usted debería poder sumar SUM (IF (vote = 'down', 1, 0)) AS DownVotes a la especificación de la columna. – Martin

0

¿Hay algún problema al hacerlo en la llamada a la base de datos? Algo así como:

$query = "SELECT id FROM votes WHERE vote = 'down'"; 
$result = mysql_query($query); 
while ($rows = mysql_fetch_assoc($result)) 
{ 
$curID = $rows['id']; 
} 
+1

Un usuario puede tener múltiples votos (es decir, varias entradas en la tabla).Esta consulta devuelve un registro por cada voto, no cada usuario, y también devolverá a los usuarios que votaron _todo_ abajo, incluso si votaron otras cosas. – octern

0
<?php 
// Make a MySQL Connection 

$query = "SELECT user, COUNT(user) FROM votes where vote == 'down' GROUP BY user"; 

$result = mysql_query($query) or die(mysql_error()); 

// Print out result 
while($row = mysql_fetch_array($result)){ 
    echo "User : ". $row['type'] ." has ". $row['COUNT(user)'] ." downvote/s."; 
    echo "<br />"; 
} 
?> 
1
select v.user from votes v where 
    0=(select count(a.vote) from votes a where a.user=v.user and a.vote='up' group by user) u 
and 
    0 <(select count(a.vote) from votes a where a.user=v.user and a.vote='down' group by user) d 
    group by user; 
Cuestiones relacionadas