MYSQL查询-获取与文章相关的最新评论


MYSQL Query - Get latest comment related to the post

我正在尝试获得与我下载的每个帖子相关的最新1或2条评论,有点像instagram,因为它们显示每个帖子的最新3条评论,到目前为止我正在获得帖子&点赞数。

现在我需要做的就是弄清楚如何获得最新的评论,不太确定如何接近它,这就是为什么我希望有更多专业知识的人可以帮助我!

这是我当前的查询:

(SELECT
        P.uuid,
        P.caption,
        P.imageHeight,
        P.path,
        P.date,
        U.id,
        U.fullname,
        U.coverImage,
        U.bio,
        U.username,
        U.profileImage,
        coalesce(Activity.LikeCNT,0),
        Activity.CurrentUserLiked
        FROM USERS AS U
        INNER JOIN Posts AS P 
        ON P.id = U.id
        LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = $id then 1 else 0 end) as CurrentUserLiked
        FROM Activity Activity
        WHERE type = 'like' 
        GROUP BY Activity.uuidPost) Activity
        ON Activity.uuidPost = P.uuid
        AND Activity.id = U.id
        WHERE U.id = $id)
UNION
        (SELECT 
        P.uuid,
        P.caption,
        P.imageHeight,
        P.path,
        P.date,
        U.id,
        U.fullname,
        U.coverImage,
        U.bio,
        U.username,
        U.profileImage,
        coalesce(Activity.LikeCNT,0),
        Activity.CurrentUserLiked
        FROM Activity AS A
        INNER JOIN USERS AS U 
        ON A.IdOtherUser=U.id
        INNER JOIN Posts AS P 
        ON P.id = U.id
        LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = $id then 1 else 0 end) as CurrentUserLiked
    FROM Activity Activity
    WHERE type = 'like' 
    GROUP BY Activity.uuidPost) Activity
    ON Activity.uuidPost = P.uuid
    AND Activity.id = U.id
    WHERE A.id = $id)
    ORDER BY date DESC
    LIMIT 0, 5

基本上评论和点赞存储在同一个表中。

所以表是Activity,然后我有一个列comment存储评论文本,然后"type"等于"comment"。

可能没有很好地解释,但我愿意尝试并给出尽可能多的细节!

如果有人可以帮助它是非常感激的!!

在这个查询https://stackoverflow.com/users/1016435/xqbert我目前得到这个错误:

操作'='的排序规则(utf8_general_ci,隐式)和(utf8_unicode_ci,隐式)的非法混合

SELECT Posts.id,
    Posts.uuid,
    Posts.caption,
    Posts.path,
    Posts.date,
    USERS.id,
    USERS.username,
    USERS.fullname,
    USERS.profileImage,
    coalesce(A.LikeCNT,0),
    com.comment
FROM Posts 
INNER JOIN USERS 
  ON Posts.id = 145 
 AND USERS.id = 145
LEFT JOIN (SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost
    FROM Activity A
    WHERE type =  'like' 
    GROUP BY A.UUIDPOST) A
 on A.UUIDPost=Posts.uuid
LEFT JOIN (SELECT comment, UUIDPOST, @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number,@prev_value := UUIDPOST
           FROM Activity 
           CROSS JOIN (SELECT @row_num := 1) x
           CROSS JOIN (SELECT @prev_value := '') y
           WHERE type = 'comment'
           ORDER BY UUIDPOST, date DESC) Com
  ON Com.UUIIDPOSt = Posts.UUID
 AND row_number <= 2
ORDER BY date DESC
LIMIT 0, 5

最新编辑

表结构:

文章

    ----------------------------------------------------------
    | id         | int(11)      |                 | not null |
    | uuid       | varchar(100) | utf8_unicode_ci | not null |
    | imageLink  | varchar(500) | utf8_unicode_ci | not null |
    | date       | timestamp    |                 | not null |
    ----------------------------------------------------------

    -------------------------------------------------------------
    | id            | int(11)      |                 | not null |
    | username      | varchar(100) | utf8_unicode_ci | not null |
    | profileImage  | varchar(500) | utf8_unicode_ci | not null |
    | date          | timestamp    |                 | not null |
    -------------------------------------------------------------

    ----------------------------------------------------------
    | id           | int(11)      |                 | not null |
    | uuid         | varchar(100) | utf8_unicode_ci | not null |
    | uuidPost     | varchar(100) | utf8_unicode_ci | not null |
    | type         | varchar(50)  | utf8_unicode_ci | not null |
    | commentText  | varchar(500) | utf8_unicode_ci | not null |
    | date         | timestamp    |                 | not null |
    ----------------------------------------------------------

这些是一些例子,在"Activity"表中,在这种情况下"type"将总是等于"comment"。

总结一切和渴望的结果:

当我查询用户帖子时,我希望能够进入"活动"表并获得最新的 2个评论,他有每个帖子。也许没有评论,所以很明显它会返回0,也许那个帖子有100条评论。但是我只想得到最近的2条评论。

一个例子可以看看Instagram是如何做到的。对于每个帖子显示最近的评论1,2或3....

希望这对你有帮助!

小提琴链接

此错误信息

排序规则(utf8_general_ci,IMPLICIT)和(utf8_unicode_ci,隐式)for操作'='

通常与列和表的定义有关。它通常意味着在等号的两边有不同的排序。你需要做的就是选择一个,并将该决定包含在你的查询中。

这里的排序问题是在@prev_value的CROSS JOIN中,需要使用显式的排序。

我还稍微改变了"row_number"逻辑到单个交叉连接,并将if逻辑移动到选择列表的极端。

下面显示了一些示例数据。需要使用样例数据来测试查询。任何试图用工作实例回答你的问题的人都需要数据。我在这里提到它有两个原因。

  1. 以便您理解我呈现的任何结果
  2. 以便将来当您询问另一个SQL相关问题时,您了解提供数据的重要性。你这样做不仅对我们更方便。如果提问者提供了样本数据,那么提问者就已经理解了——这不会是一些陌生人花了一些时间来帮忙的发明。
示例数据

请注意表中缺少一些列,只有表详细信息中指定的列被包括在内。

此示例数据对单个帖子有5条评论(没有记录点赞)

CREATE TABLE Posts 
(
`id` int, 
`uuid` varchar(7) collate utf8_unicode_ci,
`imageLink` varchar(9) collate utf8_unicode_ci, 
`date` datetime
 );
    
INSERT INTO Posts(`id`, `uuid`, `imageLink`, `date`)
VALUES
(145, 'abcdefg', 'blah blah', '2016-10-10 00:00:00') ;
CREATE TABLE   USERS
(
`id` int, 
`username` varchar(15) collate utf8_unicode_ci,
 `profileImage` varchar(12) collate utf8_unicode_ci,
 `date` datetime
) ;
        
INSERT INTO     USERS(`id`, `username`, `profileImage`, `date`)
VALUES
(145, 'used_by_already', 'blah de blah', '2014-01-03 00:00:00') ;
    
    
CREATE TABLE Activity
(
`id` int, 
`uuid` varchar(4) collate utf8_unicode_ci, 
`uuidPost` varchar(7) collate utf8_unicode_ci,
 `type` varchar(40) collate utf8_unicode_ci, 
`commentText` varchar(11) collate utf8_unicode_ci, `date` datetime
) ;
        
INSERT INTO Activity (`id`, `uuid`, `uuidPost`, `type`, `commentText`, `date`)
 VALUES
(345, 'a100', 'abcdefg', 'comment', 'lah lha ha', '2016-07-05 00:00:00'),
(456, 'a101', 'abcdefg', 'comment', 'lah lah lah', '2016-07-06 00:00:00'),
(567, 'a102', 'abcdefg', 'comment', 'lha lha ha', '2016-07-07 00:00:00'),
(678, 'a103', 'abcdefg', 'comment', 'ha lah lah', '2016-07-08 00:00:00'),
(789, 'a104', 'abcdefg', 'comment', 'hla lah lah', '2016-07-09 00:00:00') ;

[SQL标准行为:每个Post查询2行]

这是我最初的查询,有一些更正。我更改了选择列表的列顺序,以便在我显示结果时您可以轻松地看到一些与注释相关的数据。请研究他们提供的结果,以便您了解查询将做什么。前面以#开头的列在我正在使用的示例数据中不存在,原因我已经指出了。

SELECT
      Posts.id
    , Posts.uuid
    , rcom.uuidPost
    , rcom.commentText
    , rcom.`date` commentDate 
    #, Posts.caption
    #, Posts.path
    , Posts.`date`
    , USERS.id
    , USERS.username
    #, USERS.fullname
    , USERS.profileImage
    , COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
            AND USERS.id = 145
LEFT JOIN (
          SELECT
                COUNT(A.uuidPost) LikeCNT
              , A.UUIDPost
          FROM Activity A
          WHERE type = 'like'
          GROUP BY
                A.UUIDPOST
          ) A ON A.UUIDPost = Posts.uuid 
LEFT JOIN (
      SELECT
            @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
          , commentText
          , uuidPost
          , `date`
          , @prev_value := UUIDPOST
      FROM Activity
      CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci  ) xy
      WHERE type = 'comment'
      ORDER BY
            uuidPost
          , `date` DESC
      ) rcom ON rcom.uuidPost  = Posts.UUID
            AND rcom.row_number <= 2
ORDER BY
      posts.`date` DESC
      ;
      
      

在SQLFiddle

中查看该查询的工作演示结果

:

|  id |    uuid | uuidPost | commentText |                   date |                      date |  id |        username | profileImage | num_likes |
|-----|---------|----------|-------------|------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg |  abcdefg | hla lah lah | July, 09 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah |         0 |
| 145 | abcdefg |  abcdefg |  ha lah lah | July, 08 2016 00:00:00 | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah |         0 |

有2行-如预期的。一行用于最近的评论,另一行用于下一个最近的评论。这是SQL的正常行为,直到在这个答案下添加注释之前,问题的读者会认为这种正常行为是可以接受的。

这个问题缺少一个清晰的"预期结果"。


[选项1:每个Post查询一行,最多2个注释,添加列]

在下面的评论中,有人透露你不想每篇文章2行,这将是一个容易的修复。这很简单,但是有很多选择,这些选择是由用户以需求的形式决定的。如果问题有"预期结果"这样我们就知道该选哪个了。尽管如此,这里还是有一个选项

SELECT
      Posts.id
    , Posts.uuid
    , max(case when rcom.row_number = 1 then rcom.commentText end) Comment_one
    , max(case when rcom.row_number = 2 then rcom.commentText end) Comment_two
    #, Posts.caption
    #, Posts.path
    , Posts.`date`
    , USERS.id
    , USERS.username
    #, USERS.fullname
    , USERS.profileImage
    , COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
            AND USERS.id = 145
LEFT JOIN (
          SELECT
                COUNT(A.uuidPost) LikeCNT
              , A.UUIDPost
          FROM Activity A
          WHERE type = 'like'
          GROUP BY
                A.UUIDPOST
          ) A ON A.UUIDPost = Posts.uuid 
LEFT JOIN (
      SELECT
            @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
          , commentText
          , uuidPost
          , `date`
          , @prev_value := UUIDPOST
      FROM Activity
      CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci  ) xy
      WHERE type = 'comment'
      ORDER BY
            uuidPost
          , `date` DESC
      ) rcom ON rcom.uuidPost  = Posts.UUID
            AND rcom.row_number <= 2
GROUP BY
      Posts.id
    , Posts.uuid
    #, Posts.caption
    #, Posts.path
    , Posts.`date`
    , USERS.id
    , USERS.username
    #, USERS.fullname
    , USERS.profileImage
    , COALESCE(A.LikeCNT, 0)
ORDER BY
      posts.`date` DESC
      ;

参见在SQLFiddle

上工作的第二个查询

查询结果2:

|  id |    uuid | Comment_one | Comment_two |                      date |  id |        username | profileImage | num_likes |
|-----|---------|-------------|-------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg | hla lah lah |  ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah |         0 |

**选项2,将最近的注释连接到一个逗号分隔的列表中**

SELECT
      Posts.id
    , Posts.uuid
    , group_concat(rcom.commentText) Comments_two_concatenated
    #, Posts.caption
    #, Posts.path
    , Posts.`date`
    , USERS.id
    , USERS.username
    #, USERS.fullname
    , USERS.profileImage
    , COALESCE(A.LikeCNT, 0) num_likes
FROM Posts
INNER JOIN USERS ON Posts.id = 145
            AND USERS.id = 145
LEFT JOIN (
          SELECT
                COUNT(A.uuidPost) LikeCNT
              , A.UUIDPost
          FROM Activity A
          WHERE type = 'like'
          GROUP BY
                A.UUIDPOST
          ) A ON A.UUIDPost = Posts.uuid 
LEFT JOIN (
      SELECT
            @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number
          , commentText
          , uuidPost
          , `date`
          , @prev_value := UUIDPOST
      FROM Activity
      CROSS JOIN ( SELECT @row_num := 1, @prev_value := '' collate utf8_unicode_ci  ) xy
      WHERE type = 'comment'
      ORDER BY
            uuidPost
          , `date` DESC
      ) rcom ON rcom.uuidPost  = Posts.UUID
            AND rcom.row_number <= 2
GROUP BY
      Posts.id
    , Posts.uuid
    #, Posts.caption
    #, Posts.path
    , Posts.`date`
    , USERS.id
    , USERS.username
    #, USERS.fullname
    , USERS.profileImage
    , COALESCE(A.LikeCNT, 0)
ORDER BY
      posts.`date` DESC
      

查看SQLFiddle

上的第三个查询

查询结果3:

|  id |    uuid | Comments_two_concatenated |                      date |  id |        username | profileImage | num_likes |
|-----|---------|---------------------------|---------------------------|-----|-----------------|--------------|-----------|
| 145 | abcdefg |    hla lah lah,ha lah lah | October, 10 2016 00:00:00 | 145 | used_by_already | blah de blah |         0 |

**摘要**

我已经展示了3个查询,每个查询只显示2个最近的评论,但每个查询都以不同的方式进行。第一个查询(默认行为)将为每个帖子显示2行。选项2添加了一列,但删除了第二行。选项3连接最近的两条注释。

请注意:

  • 问题缺少涵盖所有列的表定义
  • 问题缺少任何样本数据,这使得您更难以理解这里呈现的任何结果,也使我们更难准备解决方案
  • 这个问题也缺乏一个明确的"预期结果"。(想要的输出),这导致了回答
  • 的进一步复杂性。

我确实希望额外提供的信息将有所用处,并且到目前为止,您也知道SQL将数据显示为多行是正常的。如果你不想要那种正常的行为,请在你的问题中具体说明你真正想要的是什么。


后记。要包含"follows"的另一个子查询您可以使用与已有子查询类似的子查询。它可以添加在该子查询之前或之后。您也可以在sqlfiddle中看到它的使用

LEFT JOIN (
          SELECT
                COUNT(*) FollowCNT
              , IdOtherUser
          FROM Activity
          WHERE type = 'Follow'
          GROUP BY
                IdOtherUser
          ) F ON USERS.id = F.IdOtherUser

虽然添加另一个子查询可以解决您对更多信息的需求,但总体查询可能会随着数据的增长而变慢。一旦确定了真正需要的功能,就应该考虑在这些表上需要哪些索引。(我相信你会被建议单独询问这个建议,如果你这样做了,请确保你包括1。表的完整DDL和2。查询的解释计划

我有点迷失在你的查询,但如果你想一次下载多个帖子的数据,这不是一个好主意,包括评论数据在第一个查询,因为你会包括所有的数据关于帖子和张贴用户多次。您应该运行另一个将帖子与评论连接起来的查询。比如:

SELECT 
A.UUIDPost, 
C.username,
C.profileImage, 
B.Comment,
B.[DateField]
FROM Posts A JOIN 
Activities B ON A.uuid = B.UUIDPost JOIN
Users C ON B.[UserId] = C.id 

,并使用该数据显示您的评论与评论用户id,名称,图像等。

每篇文章只有3条评论,你可以看看这篇文章:

使用SQL

从表中每个组中选择前3个值

如果你确定评论表或这篇文章中没有重复的行:

如何使用SQL从表中有重复项的每个组中选择前3个值

,如果您不确定的话(尽管由于表中的DateField,这应该是不可能的)。

未经测试:我建议将一些示例数据和显示问题的现有表结构放在一起进行SQL操作;这样我们就可以处理响应并确保与模式的功能。

所以我们使用一个变量来模拟一个窗口函数(比如row_number)

在这个例子中是@Row_num和@prev_Value。@Row_number跟踪每个帖子的当前行(因为一个帖子可能有很多评论),然后当遇到新的帖子ID (UUIDPOST?)时,row_num变量被重置为1。当当前记录的uidpost匹配变量@prev_Value时,我们只需将该行增加1。

该技术允许我们根据日期或活动ID降序分配行号。由于每个交叉连接只产生1条记录,因此不会出现重复的记录。然而,由于我们用row_number <= 2我们只得到新添加的左连接中最近的两条注释。

假设帖子与用户的关系是多对一,这意味着一个帖子只能有一个用户。

类似这样的内容:虽然我不确定最后的左连接,但我需要更好地理解活动表的结构,从而对原始问题进行注释。

SELECT Posts.id,
        Posts.uuid,
        Posts.caption,
        Posts.path,
        Posts.date,
        USERS.id,
        USERS.username,
        USERS.fullname,
        USERS.profileImage,
        coalesce(A.LikeCNT,0)
        com.comment
    FROM Posts 
    INNER JOIN USERS 
      ON Posts.id = 145 
     AND USERS.id = 145
    LEFT JOIN (SELECT COUNT(A.uuidPost) LikeCNT, A.UUIDPost
        FROM Activity A
        WHERE type =  'like' 
        GROUP BY A.UUIDPOST) A
     on A.UUIDPost=Posts.uuid

  --This join simulates row_Number() over (partition by PostID, order by activityID desc)  (Nice article [here](http://preilly.me/2011/11/11/mysql-row_number/) several other examples exist on SO already.
   --Meaning.... Generate a row number for each activity from 1-X restarting at 1 for each new post but start numbering at the newest activityID)
    LEFT JOIN (SELECT comment, UUIDPOST, @row_num := IF(@prev_value=UUIDPOST,@row_num+1,1) as row_number,@prev_value := UUIDPOST
               FROM ACTIVITY 
               CROSS JOIN (SELECT @row_num := 1) x
               CROSS JOIN (SELECT @prev_value := '') y
               WHERE type = 'comment'
               ORDER BY UUIDPOST, --Some date or ID desc) Com
       on Com.UUIIDPOSt = Posts.UUID
       and row_number < = 2

  -- Now since we have a row_number restarting at 1 for each new post, simply return only the 1st two rows.
    ORDER BY date DESC
    LIMIT 0, 5

我们必须把& row_number <连接本身>

此外,我们可能应该看看"评论"字段,以确保它不是空白或null,但让我们确保这首先工作。

这种类型的评论已经发布了很多次,对于大多数人来说,试图获得"最新的每个"似乎总是一个绊脚石和join/子查询噩梦。

特别是对于web界面,你可能会更好地添加一个列(或2或3)到一个表,是你的活动"posts"表,如Latest1, Latest2, Latest3。

然后,通过插入到您的评论表中,在您的表上有一个插入触发器,用最新的ID更新主帖。这样表上就一直有那个ID,没有任何子连接。现在,正如您所提到的,您可能希望有最后2或3个id,然后添加3个示例列,并让插入触发器到帖子评论细节中,对主帖子表进行更新,例如

update PrimaryPostTable
   set Latest3 = Latest2,
       Latest2 = Latest1,
       Latest1 = NewDetailCommentID
   where PostID = PostIDFromTheInsertedDetail

这将不得不在MySQL下形式化为一个适当的触发器,但应该很容易实现。你可以用最新的1作为列表的初始值,然后随着新帖子的出现,它会自动将最新的帖子滚动到第1、2、3个位置。最后,您的查询可以简化为类似

的内容。
Select
      P.PostID,
      P.TopicDescription,
      PD1.WhateverDetail as LatestDetail1,
      PD2.WhateverDetail as LatestDetail2,
      PD3.WhateverDetail as LatestDetail3
   from
      Posts P
         LEFT JOIN PostDetail PD1
            on P.Latest1 = PD1.PostDetailID
         LEFT JOIN PostDetail PD2
            on P.Latest2 = PD2.PostDetailID
         LEFT JOIN PostDetail PD3
            on P.Latest3 = PD3.PostDetailID
   where
      whateverCondition

通常不希望对数据进行反规范化。但是,在这种情况下,对于在for - each类型的查询中获取这些"最新"条目来说,它是一个很好的简化器。好运。

这是一个在MySQL中完全工作的示例,因此您可以看到表和sql插入的结果,以及通过触发器更新主post表的自动冲压。然后查询post表,您可以看到最近的帖子如何自动滚动到第一、第二和第三个位置。最后一个联接显示了如何从每个"post activity"中提取所有数据

CREATE TABLE Posts
(   id int, 
    uuid varchar(7),
    imageLink varchar(9),
    `date` datetime,
    ActivityID1 int null,
    ActivityID2 int null,
    ActivityID3 int null,
    PRIMARY KEY (id)
);
CREATE TABLE Activity
(   id int, 
    postid int,
    `type` varchar(40) collate utf8_unicode_ci, 
    commentText varchar(20) collate utf8_unicode_ci, 
    `date` datetime,
    PRIMARY KEY (id)
);
DELIMITER //
CREATE TRIGGER ActivityRecAdded
AFTER INSERT ON Activity FOR EACH ROW
BEGIN
    Update Posts
        set ActivityID3 = ActivityID2,
            ActivityID2 = ActivityID1,
            ActivityID1 = NEW.ID
        where
            ID = NEW.POSTID;
END; //
DELIMITER ;

INSERT INTO Posts
    (id, uuid, imageLink, `date`)
    VALUES
    (123, 'test1', 'blah', '2016-10-26 00:00:00');
INSERT INTO Posts
    (id, uuid, imageLink, `date`)
    VALUES
    (125, 'test2', 'blah 2', '2016-10-26 00:00:00');

INSERT INTO Activity
    (id, postid, `type`, `commentText`, `date`)
VALUES
    (789, 123, 'type1', 'any comment', '2016-10-26 00:00:00'),
    (821, 125, 'type2', 'another comment', '2016-10-26 00:00:00'),
    (824, 125, 'type3', 'third comment', '2016-10-27 00:00:00'),
    (912, 123, 'typeAB', 'comment', '2016-10-27 00:00:00');
-- See the results after the insert and the triggers.
-- you will see that the post table has been updated with the 
-- most recent 
-- activity post ID=912 in position Posts.Activity1
-- activity post ID=789 in position Posts.Activity2
-- no value in position Posts.Activity3
select * from Posts;
-- NOW, insert two more records for post ID = 123.
-- you will see the shift of ActivityIDs adjusted
INSERT INTO Activity
    (id, postid, `type`, `commentText`, `date`)
VALUES
    (931, 123, 'type1', 'any comment', '2016-10-28 00:00:00'),
    (948, 123, 'newest', 'blah', '2016-10-29 00:00:00');
-- See the results after the insert and the triggers.
-- you will see that the post table has been updated with the 
-- most recent 
-- activity post ID=948 in position Posts.Activity1
-- activity post ID=931 in position Posts.Activity2
-- activity post ID=912 in position Posts.Activity3
-- notice the FIRST activity post 789 is not there as 
-- anything AFTER the 4th entry, it got pushed away.
select * from Posts;
-- Finally, query the data to get the most recent 3 items for each post.
select
        p.id,
        p.uuid,
        p.imageLink,
        p.`date`,
        A1.id NewestActivityPostID,
        A1.`type` NewestType,
        A1.`date` NewestDate,
        A2.id SecondActivityPostID,
        A2.`type` SecondType,
        A2.`date` SecondDate,
        A3.id ThirdActivityPostID,
        A3.`type` ThirdType,
        A3.`date` ThirdDate
    from
        Posts p
            left join Activity A1
                on p.ActivityID1 = A1.ID
            left join Activity A2
                on p.ActivityID2 = A2.ID
            left join Activity A3
                on p.ActivityID3 = A3.ID;

您可以创建一个测试数据库,以便不破坏您的数据库,以查看此示例。

这可能会摆脱非法的排序组合…在建立连接之后,执行以下查询:

SET NAMES utf8 COLLATE utf8_unicode_ci;

关于'latest 2'的问题,请使用mysql命令行工具,运行SHOW CREATE TABLE Posts并提供输出。(其他相关表格同上。)Phpmyadmin(和其他ui)有一种不需要进入命令行就可以执行查询的方法。

您可以通过使用子查询来实现一个非常简单的查询。首先,我在where子句中指定用户并连接帖子,因为在我看来这更符合逻辑。然后我得到所有喜欢的帖子与子查询。

现在,我们不再分组和限制组的大小,而是通过限制当前查看的日期之后的日期计数来只连接我们想要的值。

INNER JOIN活动,如果你只想显示至少有一个评论的帖子。

SELECT
  u.id,
  u.username,
  u.fullname,
  u.profileImage,
  p.uuid,
  p.caption,
  p.path,
  p.date,
  (SELECT COUNT(*) FROM Activity v WHERE v.uuidPost = p.uuidPost AND v.type = 'like') likes,
  a.commentText,
  a.date
FROM
  Users u INNER JOIN
  Posts p ON p.id = u.id LEFT JOIN
  Activity a ON a.uuid = p.uuid AND a.type = 'comment' AND 2 > (
    SELECT COUNT(*) FROM Activity v
    WHERE v.uuid = p.uuid AND v.type = 'comment' AND v.date > a.date)
WHERE
  u.id = 145


也就是说,重新设计可能是最好的,也是性能方面的(Activity很快就会包含很多条目,它们总是必须被过滤为所需的类型)。用户表可以使用自动递增的id作为主键。对于帖子,我也会添加一个自动递增的id作为主键,user_id作为外键(你也可以决定在删除时做什么,例如,使用cascade,他的所有帖子也会自动删除)。

对于评论和点赞,你可以用两个外键user_id和post_id创建分开的表(简单的例子,像这样你只能喜欢帖子,没有别的,但如果没有很多不同类型的喜欢,它仍然可以创建一个post_likes和一些其他的…_likes表,您必须考虑通常如何查询这些数据,如果这些喜欢大多是相互独立的,这可能是一个很好的选择)。