Php SQL返回重复的行

Php SQL返回重复的行,php,mysql,sql,Php,Mysql,Sql,我一直在我的网站上开发一个非常基本的feed系统,它(应该)显示所有帖子,其中: 帖子不是来自登录用户 他们都是朋友 按post\u id排序(先获取最新的) 但是,我的SQL存在一个问题,即当查询数据库表以获取行时,它将返回一个帖子,但它将由所有用户发布,而不仅仅是创建它的一个人 例如,如果用户1发布了状态“Hi”,则数据库中有5个用户;它将抓取该帖子,然后将其打印到页面上5次,并将每个用户作为海报。(请参见下面的图像示例) SQL: SELECT posts.*, users.*, frie

我一直在我的网站上开发一个非常基本的feed系统,它(应该)显示所有帖子,其中:

  • 帖子不是来自登录用户
  • 他们都是朋友
  • post\u id
    排序(先获取最新的)
  • 但是,我的SQL存在一个问题,即当查询数据库以获取行时,它将返回一个帖子,但它将由所有用户发布,而不仅仅是创建它的一个人

    例如,如果用户
    1
    发布了状态
    “Hi”
    ,则数据库中有5个用户;它将抓取该帖子,然后将其打印到页面上5次,并将每个用户作为海报。(请参见下面的图像示例)

    SQL

    SELECT posts.*, users.*, friends.* 
    FROM posts, users, friends
    WHERE posts.poster <> ? 
    AND users.user_id = posts.poster
    AND friends.areFriends = 1 AND (friends.userA = ? AND friends.userB = posts.poster) 
    OR friends.areFriends = 1 AND (friends.userA = posts.poster AND friends.userB = ?)
    ORDER BY posts.post_id desc LIMIT 20
    
    选择帖子。*、用户。*、朋友。*
    来自帖子、用户、朋友
    海报在哪里?
    和users.user_id=posts.poster
    和friends.areFriends=1和(friends.userA=?和friends.userB=posts.poster)
    或者friends.areFriends=1和(friends.userA=posts.poster和friends.userB=?)
    按邮政订购。邮政标识说明限制20
    
    供参考:

    posts.poster
    是创建帖子的人
    用户。用户id
    是同一个人的id
    friends.areFriends
    0=不是朋友,1=朋友
    friends.userA
    /
    friends.userB
    是登录用户或该用户的好友(如果有意义的话)

    我已经尝试了我所知道的各种可能的组合来解决这个问题,但是我仍然是“高级”SQL新手,似乎找不到任何东西

    我已经尽力解释我的问题,希望有人能帮助我。过去几天我一直在试图修复它,但是没有用


    干杯。

    这应该是因为您的
    所在的
    条件。更改如下:

    WHERE posts.poster <> ? 
    AND users.user_id = posts.poster
    AND friends.areFriends = 1 
    AND ((friends.userA = ? AND friends.userB = posts.poster) OR (friends.userA = posts.poster AND friends.userB = ?))
    
    posts.poster在哪里?
    和users.user_id=posts.poster
    AND friends.areFriends=1
    和((friends.userA=?和friends.userB=posts.poster)或(friends.userA=posts.poster和friends.userB=?)
    

    编写条件时,它将返回满足所有其他条件的行或
    friends.areFriends=1和(friends.userA=posts.poster和friends.userB=?)
    。因此,即使是不满足
    users.user\u id=posts.poster的行也将被返回。但在我编写条件时,OR被括在括号中。

    我假设查询必须返回用户朋友的帖子
    。首先查找朋友,然后查找他们的帖子,然后查找他们的其他数据

    SELECT  pp.*, uu.* 
    FROM     (select distinct case when ? = friends.userB then friends.userA else friends.userB end as user_id
             from friends 
             where ? in (friends.userA, friends.userB)
             and friends.areFriends = 1 
             ) f
    join posts pp on pp.poster = f.user_id
    join users uu on uu.user_id = pp.poster
    

    创建内部联接的经典方法更具可读性,并帮助您理解代码不起作用的原因。此外,它是SQL的一种代码约定,因此它还帮助其他人(如我)理解您

    我已重新编写您的代码以使用
    内部联接
    。试试这个

    SELECT @userId := ?;
    
    SELECT posts.*, users.*, friends.* 
    FROM friends
    JOIN users ON users.user_id = 
        CASE friends.userA
        WHEN @userId
        THEN friends.userB
        ELSE friends.userA END
    JOIN posts ON posts.poster = users.user_id
    WHERE friends.userA = @userId OR friends.userB = @userId
    ORDER BY posts.post_id DESC LIMIT 20;
    
    确保
    朋友
    表中没有重复。以下查询将帮助您完成此操作:

    SELECT User1, User2, COUNT(*) as DupeCount
    FROM 
    (
        SELECT
            CASE WHEN friends.userA < friends.userB THEN friends.userA ELSE friends.userB END AS User1,
            CASE WHEN friends.userA < friends.userB THEN friends.userB ELSE friends.userA END AS User2
        FROM friends
    ) AS F
    GROUP BY User1, User2
    HAVING COUNT(*) > 1
    
    选择User1、User2、COUNT(*)作为DupeCount
    从…起
    (
    挑选
    当friends.userA
    使用SQL连接…@AmanKumar对于投票支持close的n00b hahaTo来说相当神秘;请解释我可以如何改进我的问题,以便为您缩小范围:)我觉得我已经尽可能清楚地说明了这一点,但我愿意听取建议@Jibin应该将此作为答案发布,伙计!:D@GROVER好的,我是soryThanks,我来测试一下!介意告诉我这是怎么回事,它和我的有什么不同吗?:)Saeed,只是为了让我将来能从中学习答案,这些答案只是代码,没有解释已经修复/改进的内容。Saeed,我改进了我的答案Saeed,重复是因为没有正确地将表格连接在一起。这是一个非常常见的错误。使用
    连接
    而不是通过条件
    users.user\u id=posts.poster
    ,可以更安全地避免这些问题,但可以通过这种方式来完成,我将测试它!)有什么原因需要将userId声明为INT吗?@GROVER没有,我刚刚创建了一个变量来停止在任何地方使用
    。类型不重要。哦,那真聪明!:D谢谢,这肯定会有帮助。我在查询数据库时尝试过使用它作为SQL,但是它说查询执行不正确:/有什么原因吗?我还注意到它的格式并不像通常那样崇高(即:
    选择
    来自
    其中
    e.t.c;不要变为彩色)更新:我注意到当删除
    声明@userId INT=从我的查询中,格式化工作正常。