SQL 查询来自用户和关注用户的 select 个帖子不包括自己的帖子

SQL Query to select posts from user and followed users is not including own posts

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

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 发表的帖子?

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

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;

如果我没理解错的话,你基本上想要一个 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;

我正要post一个 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 的解决方案可能会更好 - 至少更简洁 - 但我认为它不像 posted.

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;

I'm building a query that should return the last 10 posts by $userId and the users it is following.

所以,这里有两个任务:

  1. 每组获取前N条记录
  2. 对给定用户应用查询,并对相关用户应用相同的查询

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

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)

参见:

根据您的条件从 table 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.