【问题标题】:SQL Query to select posts from user and followed users is not including own posts从用户和关注的用户中选择帖子的 SQL 查询不包括自己的帖子
【发布时间】:2020-04-18 16:22:04
【问题描述】:

我正在构建一个查询,该查询应返回 $userId 及其关注的用户的最后 10 个帖子(默认排序)。

带有查询的最小示例的 SQL Fiddle:https://www.db-fiddle.com/f/i5ByFAXwADj5pfjCTn1g1m/2

数据库结构非常简单:

posts (id, root, user, content)
users (id, username)
following (user_id, followed)

这是我目前用来获取所有帖子的查询:

SELECT posts.id, posts.content, users.id AS user_id, users.username
FROM posts
     LEFT JOIN users ON posts.user = users.id
WHERE LIMIT 10

查询正在运行,但它不加区别地列出了每个用户的帖子。

这是我构建的查询,用于排除 $userId 未关注的用户的帖子,但不包括 $userId 自己的帖子:

SELECT posts.id, posts.content, users.id AS user_id, users.username
FROM following
     LEFT JOIN posts ON posts.user = '$userId' OR posts.user = following.followed
     LEFT JOIN users ON posts.user = users.id
WHERE (following.user_id = '$userId' OR following.user_id = NULL) LIMIT 10

我尝试用INNER JOINRIGHT JOIN 替换LEFT JOIN posts,但没有成功。我找不到错误,为什么查询中没有包含$userId 的帖子?

我也尝试过从帖子中选择并加入关注者,但它返回了重复的内容:

SELECT posts.id, posts.content, users.id AS user_id, users.username
FROM posts
     LEFT JOIN following ON following.user_id = '$userId'
     LEFT JOIN users ON posts.user = users.id
WHERE (posts.user = '$userId' OR posts.user = following.followed)
LIMIT 10;

【问题讨论】:

标签: mysql sql database posts


【解决方案1】:

我正要发布一个 UNION 解决方案

SELECT
    post_id,
    content,
    user_id,
    username
FROM
    (SELECT
        posts.id post_id,
        content,
        users.id user_id,
        username
    FROM
        posts INNER JOIN
            users
        ON user = users.id
    UNION SELECT
        posts.id,
        content,
        users.id,
        username
    FROM
        posts INNER JOIN (
            following INNER JOIN
                users
            ON user_id = users.id
        ) ON user = followed
    ) p
WHERE
    user_id = 1
LIMIT 10;

然后我看到@Gordon Linoff 的解决方案可能更好——至少更简洁——但我认为它不像发布的那样有效。

SELECT
    posts.id,
    content,
    users.id,
    username
FROM
    posts INNER JOIN
        users
    ON user = users.id
WHERE
    users.id = 1
    OR EXISTS (
        SELECT
            *
        FROM
            following
        WHERE
            followed = user
            AND user_id = 1
    )
LIMIT 10;

【讨论】:

【解决方案2】:

在你的条件下从表posts获取帖子并加入users

select p.id, p.content, u.id AS user_id, u.username
from (
  select *
  from posts
  where user = '$user_id'
     or user in (select user_id from following where followed = '$user_id')
) p inner join users u on u.id = p.user  
order by p.id desc limit 10

请注意,如果最后 10 个帖子来自该用户关注的用户,则结果可能不包含用户 '$user_id' 的帖子。
请参阅demo

【讨论】:

  • 您的查询运行良好,因此我投了赞成票。但在我了解哪个性能更好之前,我无法更改已接受的答案
【解决方案3】:

我正在构建一个查询,该查询应返回 $userId 及其关注的用户的最后 10 个帖子。

所以,这里有两个任务:

  1. 获取每组的前 N ​​条记录
  2. 将查询应用于给定用户 PLUS 与相关用户相同

我会做这样的事情(伪代码):

ids = query('SELECT user_id FROM following WHERE followed = :id)', userId).pluck('user_id');
ids.push(userId);
SELECT x.id, x.user_id, x.content
FROM (
      SELECT  @num := IF(@id = user_id, @num + 1, 1) AS num, 
              @id := posts.user_id as x_user_id, 
              posts.*
      FROM 
          (SELECT @num := null, @id := null) x, 
          posts
      WHERE posts.user_id IN(:ids)
      ORDER BY posts.id DESC
) AS x
WHERE x.num <= 10

(https://www.db-fiddle.com/f/aiBUwqDApJp6foyq13ZZ2u/1)

见:

【讨论】:

  • 如果我理解正确,如果我关注 10K 用户,我的查询字符串包含所有 10K 用户 ID,对吗?
  • 是的。如果您想限制您的新闻源,请添加一些附加条件。就像“本周已发布”之类的。
  • 好的,非常感谢,但我无意以这种方式构建查询字符串
【解决方案4】:

如果我理解正确,你基本上想要一个EXISTS 子句:

SELECT p.id, p.content, u.id AS user_id, u.username
FROM posts p JOIN
     users u
     ON p.user = u.id
WHERE u.id <> ?   -- ? is the userid AND
      EXISTS (SELECT 1
              FROM following f
              WHERE f.followed = ? AND
                    f.user_id = u.id
             )
LIMIT 10;

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2012-01-24
  • 2013-10-12
  • 2015-11-08
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多