[Resuelto] JOIN query y mysqli_num_rows

Iniciado por gAb1, 22 Octubre 2014, 22:51 PM

0 Miembros y 1 Visitante están viendo este tema.

gAb1

Hola, me gustaría saber como se usa el count cuando necesito juntar varias sentencias en una misma consulta.

Estoy haciendo una lista de fotos con likes: primero necesito obtener todas las imagenes de una tabla, segundo comprobar (row count) si el usuario ya le dio like a la imagen sacando el id de la imagen y por ultimo otro row count para saber cuantos likes tiene la imagen, usando el mismo id de imagen.

Tengo algo así, me falta el count, no estoy seguro de como hacerlo y si usar INNER JOIN:

Código (sql) [Seleccionar]
SELECT user_uploads.* AS uu, members.*, COUNT(img_id, user_id) AS usr_liked, COUNT(img_id) AS total_likes
FROM user_uploads
INNER JOIN members AS m ON m.id = uu.user_id -- owner info
INNER JOIN img_likes AS il ON il.img_id = uu.imgID AND il.user_id = ? -- check if logged in user already liked
INNER JOIN img_likes AS ilt ON ilt.img_id = uu.imgID -- total likes
GROUP BY img_id, user_id
ORDER BY up_time DESC


Tengo un prepared statement y luego con un foreach imprimo todas las imagenes. Pero antes de empezar a imprimir la lista de fotos tengo que comprobar si el usuario ya le dio like a la imagen para cambiar el boton (like o unlike) y sacar el numero total de likes.

Tampoco se, en este caso de juntar tablas, como comprobar el row count, normalmente uso mysqli_num_rows($stmt); pero ahora no se si esto funciona asi.

Código (php) [Seleccionar]
if ($stmt = $mysqli->prepare("SELECT user_uploads.* AS uu, members.*, COUNT(img_id, user_id) AS usr_liked, COUNT(img_id) AS total_likes
                              FROM user_uploads
                              INNER JOIN members AS m ON m.id = uu.user_id
                              INNER JOIN img_likes AS il ON il.img_id = uu.imgID AND il.user_id = ?
                              INNER JOIN img_likes AS ilt ON ilt.img_id = uu.imgID
                              GROUP BY img_id, user_id
                              ORDER BY up_time DESC")) {
$stmt->bind_param('i', $id);
$Items = $stmt->execute(); // get photos

foreach ($Items as $ItemInfo) {

$liked = mysqli_num_rows($Items); // como hacerlo ahora?
$total_likes = mysqli_num_rows($Items);

$img_id = $aItemInfo['img_id'];

if ($liked == 0) {
$like = 'Me gusta';
}
else if ($liked == 1) {
$like = 'Ya no me gusta';
}

$photo_list .= '
// lista de fotos
// boton like
<span class="total_likes" id="lik' . $status_id . '">' . $totallikes . '</span>
<a id="' . $total_likes . '" class="likes">' . $like . '</a>
';
}
}


Si hay alguna forma mejor de hacer esto me gustaría saberla.

Gracias!

dimitrix

Vale, perdona, pero hoy estoy espeso y puesto que hace tres días que nadie te comenta, te dejaré varias info por si te interesan...


Puedes hacer esto, si el valor $ID es 100...:

Código (sql) [Seleccionar]
SELECT ID, name, (SELECT COUNT(*) FROM images WHERE ID_post=$ID) as total_imagenes FROM POST WHERE ID=$ID

Con esto, al existir sólo una tupla/celda, le estarás dando la cantidad de imágenes que tiene ese post al valor "total_imagenes", en el que caso de que no existieran, el valor retornado sería 0.

Hoy estoy un poco espeso...




gAb1

#2
Gracias por la respuesta, toda ayuda es bien recibida.

Si no me equivoco ¿eso es una subquery?

Código (sql) [Seleccionar]
SELECT user_uploads.*, -- esta es la tabla de las imagenes
   (SELECT COUNT(*) FROM img_likes WHERE img_id = user_uploads.imgID) AS total_likes
FROM user_uploads
ORDER BY up_time DESC


Lo que hace esa query es, obtener todo de la tabla imagenes (user_uploads) y hacer un count de los likes que tiene cada una de las imágenes, ¿no?

Mi única duda aquí es, si la imagen de la id seleccionada seria la misma id usada para hacer el COUNT, no vaya a ser que muestre los likes de una imagen en otra :P

Y en el código php sería poner esto?

Código (php) [Seleccionar]
$total_likes = $ItemInfo['total_likes'];

Gracias!

Edito: Vale ya he conseguido que funcione:

Código (SQL) [Seleccionar]
SELECT
    uu.*,
    m.*,
    (
        SELECT COUNT(t.*)
        FROM img_likes t
        WHERE t.img_id = uu.imgID AND t.user_id = ?
    ) AS user_likes,
    (
        SELECT COUNT(t.*)
        FROM img_likes t
        WHERE t.img_id = uu.imgID
    ) AS total_likes
FROM user_uploads uu
INNER JOIN members m ON m.id = uu.user_id
ORDER BY uu.up_time DESC


Sobre el rendimiento, ¿será mucha carga para el servidor hacer esos COUNT? (cuando hayan bastante entradas en la tabla)

Gracias!

dimitrix

¿Define bastante?

Si estás en un windows, hasta 300,000 ni tendrás problemas, si estás en un VPS que seguramente usará linux ubunut/centOS tranquilamente puedes tener 3 millones...

Me alegro de haber ayudado... aunque llevara unas cervecitas xDDDD




gAb1

Eso son muchas!! hehehe

Por supuesto xD

Lo marco como solucionado.