我正在尝试获取与我下载的每个帖子相关的最新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存储注释文本,然后“类型”等于“注释”。
Activity
comment
可能解释得不是很好,但我愿意尝试并提供尽可能多的细节!
如果有人可以帮助,将不胜感激!!
更新
在给出的此查询中,我目前收到此错误:
操作’=’的排序规则(utf8_general_ci,IMPLICIT)和(utf8_unicode_ci,IMPLICIT)的非法混合
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 | ----------------------------------------------------------
这些是一些示例,在这种情况下,“活动”表中的“类型”将始终等于“注释”。
总结一切和欲望的结果:
当我查询用户帖子时,我希望能够进入“活动”表并为他的每个帖子获取 最新的 2条评论。也许没有评论,所以很明显它将返回0,或者该帖子可能有100条评论。但我只想获取最新/最近的2条评论。
一个例子可能是看Instagram如何做到这一点。对于每个帖子,显示最新的评论1、2或3 …
希望这可以帮助!
此错误讯息
通常是由于您定义了列和表。通常,这意味着等号的两边都有不同的排序规则。您需要做的是选择一个并将该决定包括在您的查询中。
这里的排序规则问题在@prev_value的CROSS JOIN中,需要使用显式的排序规则。
我也将“ row_number”逻辑略微更改为单个交叉联接,并将if逻辑移至选择列表的极端。
一些样本数据显示在下面。需要样本数据来测试查询。任何尝试通过工作示例回答您的问题的人都将需要数据。我将其包含在此处的原因是双重的。
样本数据
请注意,表中缺少某些列,仅包括表详细信息中指定的列。
该样本数据对单个帖子有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:每个邮政查询一行,最多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将最近的2条评论串联起来。
请注意:
我确实希望提供的附加信息有用,并且到目前为止,您还知道SQL将数据显示为多行是正常的。如果您不希望这种正常行为,请具体说明您在问题中真正想要的是什么。
后记。要包含另一个“遵循”子查询,可以使用与已有子查询类似的子查询。它可以在该子查询之前或之后添加。您还可以看到它在使用中sqlfiddle这里
LEFT JOIN ( SELECT COUNT(*) FollowCNT , IdOtherUser FROM Activity WHERE type = 'Follow' GROUP BY IdOtherUser ) F ON USERS.id = F.IdOtherUser
虽然添加另一个子查询可能会解决您对更多信息的需求,但总体查询可能会随着数据增长而变慢。确定了您真正需要的功能后,可能值得考虑在这些表上需要哪些索引。(我相信建议您单独咨询该建议,并且如果确实要确保包含1.表的完整DDL和2.查询的解释计划。)