开发者

SQL JOINS retrieving and displaying twice

I am joining 2 tables and trying to display the results. Only problem is every result is duplicated. I have 2 tables, messages and follow. Messages are what a certain user inputs, and I want it to display only to the people that follow that certain user.

Messages | Follow
-id        -id
-message   -mem1 (logged in user)
-userid    -mem2 (followed user)
-created

$display ="";
$sql = mysql_query("
SELECT * FROM messages AS me 
JOIN follow AS fl 
ON me.userid = fl.mem2 
WHERE fl.mem1 = $id (logged in user)
ORDER BY me.created 
DESC LIMIT 10
") or die(mysql_error());
while($row=mysql_fetch_array($query)){
$msgid = $row["id"];
$message = $row["message"];
$userid = $row["userid"];
$created = $row["created"];

$display .="<?php echo $userid; ?> : <?php echo $message; ?><br />
<?php echo $created; ?>";
}

In the database t开发者_运维问答here are no duplicates, just on the retrieve. Thanks for the input!

Edited: Display Code


You're getting "double" results, most likely because the query results in something different then you expect.

If I understand your table-structure correctly; you have a one-to-many relation from messages to followers.

In your query, however, you fetch combinations of messages and followers. Each line will consist of a unique combination of message<>follower.

In short; when a single message has two followers, you'll get two rows in the result with the same message; but a different follower entry.

If you want to show each message once; and then list all followers per message you can either use group-by functions (e.g group_concat) and group-by on message entries. The other possibility is to fetch the followers in a separate query once you've retrieved the message row, and then print the results from that query as the followers for that message.

If you're simply trying to get the number of followers; you can use a group-by on the UID of your message table and add a count on the UID or user ID of the follower table. (Do not that with group-by, the select * from shouldn't be used; but separate columns can.)


There's really only a few things that could cause the records to duplicate - try breaking down the query into basic components to see if there are more than one record:

SELECT * FROM follow WHERE mem1 = [id];
SELECT * FROM messages WHERE userid = [mem2 from previous result];

If either of the previous statements return more than one record, than the problem lies there. Other than that, I'd look at the PHP code to see if you're doing something there.

As for the query itself, I have a few recommendations:

  • Place the table with the filter first - the sooner you can narrow the results the better.
  • Specify a field list instead of using '*' - this will be a tiny bit more efficient, and clarify what you're after. Also, it will give 'DISTINCT' a fighting chance to work...

Here's an example:

SELECT DISTINCT me.id, me.message, me.userid, me.created
    FROM follow AS fl 
    INNER JOIN messages AS me ON me.userid = fl.mem2 
    WHERE fl.mem1 = :logged_in_user
    ORDER BY me.created 
    DESC LIMIT 10


If you are sure that there are no duplicates and the problem is in the query (you can check that by executing it from your database's interface), you can try two things:

  • Use the follow table as the leading one:

    SELECT messages.*
    FROM follow
    JOIN messages ON follow.mem2=messages.userid
    WHERE follow.mem1=$id
    ORDER BY messages.created DESC
    LIMIT 0,10;
    
  • Use a subquery:

    SELECT *
    FROM messages
    WHERE userid IN(
        SELECT DISCTINCT(mem2)
        FROM follow
        WHERE mem1=$id
        )
    ORDER BY created DESC
    LIMIT 0,10;
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜