php – MYSQL查询 – 获取与该帖子相关的最新评论

前端之家收集整理的这篇文章主要介绍了php – MYSQL查询 – 获取与该帖子相关的最新评论前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试获得与每个帖子相关的最新的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,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,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,那么我有一个存储注释文本的列注释,然后“type”等于“comment”.

可能不是很好的解释,但我愿意尝试尽可能多的细节!

如果有人可以帮助它非常感谢!

UPDATE

https://stackoverflow.com/users/1016435/xqbert给出的这个查询我现在得到这个错误

Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation ‘=’

SELECT Posts.id,Posts.uuid,Posts.caption,Posts.path,Posts.date,USERS.id,USERS.username,USERS.fullname,USERS.profileImage,coalesce(A.LikeCNT,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 |
    ----------------------------------------------------------

USERS

-------------------------------------------------------------
    | 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 ….

希望这可以帮助!

Fiddle link

错误消息

Illegal mix of collations (utf8_general_ci,IMPLICIT) and
(utf8_unicode_ci,IMPLICIT) for operation ‘=’

通常是由于您的列和表的定义.这通常意味着在等号的任一侧有不同的归类.您需要做的是选择一个,并在查询中包含该决定.

这里的排序规则是在@prev_value的CROSS JOIN中,需要使用明确的排序规则.

我还将“row_number”逻辑略微更改为单个交叉连接,并将if逻辑移动到选择列表的极限.

下面显示一些样品数据.需要样本数据来测试查询.任何试图通过实例解答您的问题的人都需要数据.我在这里包括的原因有两个方面.

所以你会明白我所呈现的任何结果
>以便将来当您提出另一个sql相关问题时,您将了解提供数据的重要性.这样做不仅对我们更方便.如果asker提供样本数据,那么asker将已经明白了 – 这不会是一些陌生人的发明,他们花了一些时间来帮助他们.

样品数据

请注意表中缺少一些列,仅包括表格详细信息中指定的列.

此示例数据针对单个帖子有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`,'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`,`uuidPost`,`type`,`commentText`,`date`)
 VALUES
(345,'a100','comment','lah lha ha','2016-07-05 00:00:00'),(456,'a101','lah lah lah','2016-07-06 00:00:00'),(567,'a102','lha lha ha','2016-07-07 00:00:00'),(678,'a103','ha lah lah','2016-07-08 00:00:00'),(789,'a104','hla lah lah','2016-07-09 00:00:00') ;

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

这是我的初步查询,并进行了一些更正.我更改了选择列表的列顺序,以便当我提供结果时,您会看到一些注释相关的数据.请研究他们提供的结果,以便您可以了解查询将会做什么.由于我已经注意到的原因,我正在处理的样本数据中不存在#前面的列.

SELECT
      Posts.id,rcom.uuidPost,rcom.commentText,rcom.`date` commentDate 
    #,Posts.caption
    #,Posts.`date`,USERS.username
    #,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,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
      ;

See a working demonstration of this query at SQLFiddle

Results

|  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个ROWS – 如预期.最近一次评论的一行,以及下一个最近评论的另一行.这是sql的正常行为,直到在此答案下添加评论时,问题的读者会认为这种正常行为是可以接受的.

这个问题缺乏明确的“预期成果”.

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

在下面的评论中,显示您不需要每个帖子2行,这将是一个简单的修复.那么它很简单,但是有选项,选项由用户以需求的形式决定.如果这个问题有一个“预期的结果”,那么我们知道选择哪个选项.不过这里有一个选择

SELECT
      Posts.id,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
    #,`date` DESC
      ) rcom ON rcom.uuidPost  = Posts.UUID
            AND rcom.row_number <= 2
GROUP BY
      Posts.id,Posts.uuid
    #,0)
ORDER BY
      posts.`date` DESC
      ;

See the second query working at SQLFiddle

Results of query 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,group_concat(rcom.commentText) Comments_two_concatenated
    #,0)
ORDER BY
      posts.`date` DESC

See this third query working at SQLFiddle

Results of query 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 here看到它的使用

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

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

原文链接:https://www.f2er.com/php/132634.html

猜你在找的PHP相关文章