GRUPO amigos de primer y segundo nivel

Digamos que dado un song_id y un uid, nos gustaría conocer a todos los amigos (amigos directos y amigos de amigos) a los que les gusta la misma canción:

Así es como lo estamos haciendo:

public function get_song_mates($uid, $song_id, $current_only = true, $limit = PHP_INT_MAX)
    {

        $sql    = "SELECT * 
                    FROM (
                    (
                        SELECT users . * ,  '1st' AS  `level`, 1 AS `level_i` 
                        FROM songs
                        JOIN users ON users.id = songs.user_id
                        JOIN friends AS my_friend ON my_friend.fid = users.id 
                        AND my_friend.uid = '".$uid."'                  
                        WHERE song_id =  '".$song_id."')
                    UNION (

                    SELECT second_friend . * ,  '2nd' AS  `level`, 2 AS `level_i`
                    FROM songs
                    JOIN users AS second_friend ON second_friend.id = songs.user_id
                    JOIN friends ON friends.uid = second_friend.id
                    JOIN users AS first_friend ON first_friend.id = friends.fid 
                    JOIN friends AS my_friend ON my_friend.fid = first_friend.id 
                    AND my_friend.uid = '".$uid."'                  
                    WHERE song_id =  '".$song_id."'


                    AND second_friend.id NOT IN
                        (
                            SELECT users.id 
                              FROM songs
                              JOIN users ON users.id = songs.user_id
                              JOIN friends AS my_friend ON my_friend.fid = users.id 
                               AND my_friend.uid = '".$uid."'
                             WHERE song_id = '".$song_id."'
                        )
                    ) ORDER BY `level_i` ASC, firstname, lastname
                    ) AS friend                 
                    GROUP BY id ORDER BY `level_i`";

        $users  = $this->getFromSql($sql);  
        return $users;
    }

Pero tenga en cuenta que tuvimos que agregar:

AND second_friend.id NOT IN...

para evitar mostrar al mismo usuario como amigo directo y como amigo de un amigo... Estoy bastante seguro de que necesito hacer uso de GROUP BY, pero simplemente no puedo obtener la sintaxis correcta. alguna pista aquí?

operación -Editar-

friends(uid, fid)
songs(id, user_id, song_id)
users(id, frist_name, last_name)

preguntado el 22 de mayo de 12 a las 12:05

¿Puedes describir las tablas, especialmente las CLAVES EXTRANJERAS? -

¿Usando concatenación de cadenas para generar SQL? ¿Has oído hablar de la inyección SQL? -

Lo mejor es reducir un problema presentado en SO a lo esencial. Lo esencial aquí es el SQL y no el envoltorio de PHP. La parte del trabajo actual tampoco es crucial para la pregunta. Tal como está, el SQL es ilegible porque está atado a PHP. Además, tenga cuidado SQL Injection! -

editado con tablas y filas de base de datos relevantes. básicamente tenemos el último AND NOT IN para eliminar a los amigos de amigos míos que también son amigos míos directos. para que no mostremos usuarios duplicados. Cualquier pista sería muy útil -

1 Respuestas

Se arregló así:

función pública get_song_mates($uid, $song_id, $current_only = true, $limit = PHP_INT_MAX) {

    $sql    = "SELECT DISTINCT * 
                FROM (
                (
                    SELECT users . * ,  '1st' AS  `level`, 1 AS `level_i` 
                    FROM songs
                    JOIN users ON users.id = songs.user_id
                    JOIN friends AS my_friend ON my_friend.fid = users.id 
                    AND my_friend.uid = '".$uid."'                  
                    WHERE song_id =  '".$song_id."')
                UNION (

                SELECT DISTINCT second_friend . * ,  '2nd' AS  `level`, 2 AS `level_i`
                FROM songs
                JOIN users AS second_friend ON second_friend.id = songs.user_id
                JOIN friends ON friends.uid = second_friend.id
                JOIN users AS first_friend ON first_friend.id = friends.fid 
                JOIN friends AS my_friend ON my_friend.fid = first_friend.id 
                AND my_friend.uid = '".$uid."'                  
                WHERE song_id =  '".$song_id."'";

    $users  = $this->getFromSql($sql);  
    return $users;
}

contestado el 22 de mayo de 12 a las 22:05

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