gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:34:54 25 4
gpt4 key购买 nike

我正在尝试获取与我下载的每个帖子相关的最新 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其中存储评论文本,然后“类型”等于“评论”。

可能没有很好的解释,但我愿意尝试提供尽可能多的细节!

如果有人可以提供帮助,将不胜感激!!

更新

在此查询由 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,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....

希望这可以帮助!

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 相关的问题时,您会了解提供数据的重要性。您这样做不仅对我们更方便。如果提问者提供了样本数据,那么提问者就已经理解了——这不会是某个花费了一些时间来提供帮助的陌生人的发明。

  • 样本数据
    请注意表中缺少某些列,仅包含表详细信息中指定的列。
    此示例数据对单个帖子有 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
    ;


    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 行。一行是最近的评论,另一行是下一个最近的评论。这是 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
    ;
    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
    , 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

    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. 查询的解释计划。)

    关于php - MYSQL 查询 - 获取与帖子相关的最新评论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40268501/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com