2017-05-04 22 views
0

这是我试图开始工作的查询。我处于死胡同。 SQL查询以获取最后回复的用户名和时间戳

SELECT 
    t.id AS topic_id, 
    t.title AS topic_title, 
    t.content AS topic_content, 
    t.created_at AS topic_created_at, 
    t.updated_at AS topic_updated_at, 
    t.user_id AS topic_user_id, 
    c.id AS comment_id, 
    c.content AS comment_content, 
    c.created_at AS comment_created_at, 
    max_c.username AS comment_username, 
    u.username AS topic_username 
FROM 
    topics t 
JOIN 
    (SELECT 
     c2.topic_id, c2.created_at, u2.username 
    FROM 
     comments c2 
    JOIN 
     users u2 ON c2.user_id = u2.id 
    JOIN 
     topics t2 ON c2.topic_id = t2.id 
    ORDER BY 
     c2.created_at desc) max_c ON t.id = max_c.topic_id 
JOIN 
    comments c ON max_c.created_at = c.created_at 
JOIN 
    users u ON u.id = t.user_id 
ORDER BY 
    c.created_at DESC 

很肯定的查询,这部分是不正确的:

SELECT 
    c2.topic_id, c2.created_at, u2.username 
FROM 
    comments c2 
JOIN 
    users u2 ON c2.user_id = u2.id 
JOIN 
    topics t2 ON c2.topic_id = t2.id 
ORDER BY 
    c2.created_at desc 

该查询当前显示如下。但我想通过created_at或任何合适的组合,所以我们只能得到最新的回复话题。

如果你能帮助这将是惊人的,我花了大约5个小时努力,到目前为止写这个...

我下面附上我的表迁移。

# Dump of table comments 
# ------------------------------------------------------------ 

CREATE TABLE `comments` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `content` varchar(255) DEFAULT NULL, 
    `user_id` int(11) NOT NULL, 
    `topic_id` int(11) DEFAULT NULL, 
    `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`), 
    KEY `comments_ibfk_2` (`topic_id`), 
    CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), 
    CONSTRAINT `comments_ibfk_2` FOREIGN KEY (`topic_id`) REFERENCES `topics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 



# Dump of table topics 
# ------------------------------------------------------------ 

CREATE TABLE `topics` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `title` varchar(255) DEFAULT NULL, 
    `content` text, 
    `user_id` int(11) NOT NULL, 
    `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`), 
    CONSTRAINT `topics_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 



# Dump of table users 
# ------------------------------------------------------------ 

CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `username` varchar(255) DEFAULT 'NOT NULL', 
    `email` varchar(255) DEFAULT 'NOT NULL', 
    `password` char(60) DEFAULT 'NOT NULL', 
    `admin` int(11) NOT NULL DEFAULT '0', 
    `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
+0

为了提高问题的质量(已经相当不错),请添加关于您的整个陈述意图实现的描述以及陈述部分的预期功能的描述。此外,请使用示例数据显示表格的结构,并可能使用语句扩展您的表格创建脚本以插入此数据。另外,请根据样本数据显示您希望输出的显示方式。另外,您可以参考您的声明的当前输出,但不能真正显示该输出。你在使用'MySQL','SQL-Server'等吗? – toonice

+0

那个时候用户可以启动一个主题,但不*发布一个评论吗? – toonice

+0

我们可以假设两个'用户'不能同时在同一个'Topic'上发布'Comment'吗? – toonice

回答

0

如果我理解你的问题,你所遇到的问题是子查询应返回只有最后一个用户名和时间戳,但返回所有来代替。在这种情况下,您可以在订单后使用LIMIT 1以获得所需的结果。

SELECT c2.topic_id, c2.created_at,u2.username 
    FROM comments c2 
    JOIN users u2 ON c2.user_id = u2.id 
    JOIN topics t2 ON c2.topic_id = t2.id 
    ORDER BY c2.created_at desc 
    LIMIT 1 
0

请尝试以下...

SELECT topics.id AS topic_id, 
     topics.title AS topic_title, 
     topics.content AS topic_content, 
     topics.created_at AS topic_created_at, 
     topics.updated_at AS topic_updated_at, 
     topicsUsers.user_id AS topic_user_id, 
     topicsUsers.username AS topic_username, 
     comments.id AS comment_id, 
     comments.content AS comment_content, 
     maxCreatedAt AS comment_created_at, 
     commentsUsers.user_id AS comment_user_id 
     commentsUsers.username AS comment_username, 
FROM topics 
JOIN (SELECT topic_id AS topic_id, 
       MAX(comments.created_at) AS maxCreatedAt, 
     FROM comments 
     GROUP BY topic_id 
    ) maxCreatedAtFinder ON topics.id = maxCreatedAtFinder.topic_id 
JOIN comments ON maxCreatedAtFinder.maxCreatedAt = comments.created_at 
      AND maxCreatedAtFinder.topic_id = topics.id 
JOIN users AS topicsUsers ON users.id = topics.user_id 
JOIN users AS commentsUsers ON users.id = comments.user_id 
ORDER BY maxCreatedAt DESC 

,尽我所能从你的问题告诉,你正在寻找显示每个topic的详细信息(包括对的user详细信息列表user谁发起Topic)以及Topic的最新comment以及user谁发布了comment的详细信息。

我的声明遵循与您提供的声明类似的结构。我已从子查询中删除JOINtopics,因为topic_idtopics的唯一细节,我们希望子查询可以从comments获得topic_id

获得的user的谁发布的最新commentTopic将分组复杂化,并导致更多的细节被联接比如果我们加入CommentsUsers子查询外执行。所有子查询确实需要获取每个Topic的最近值created_at。因此,我已将JOIN删除为Users以及相关的字段选择。

在主要发言中,我一直保持着子查询的INNER JOINtopics,从而有效地追加的created_at最大值从commentstopics其相应的记录。

我再取所得的数据集和以这样的方式将其加入comments一个topic和从commentscreated_at其相关联的最近的值具有每个comment的该topic内容即created_at值附加到它。请注意,虽然不太可能同时创建属于topic的两个comments,并因此具有相同的值created_at。这两个记录将被加入到正在形成的数据集中。在没有相反指示的情况下,我认为这是理想的行为,并且已经允许。

我再取所得的数据集和JOIN它的users两个实例,一个基于所述topic_id以及基于所述user_idcomment另一个。这具有附加到我们的数据集中的每个记录的效果,useruser谁创建Topicuser谁发布了最新的comment(s)的细节。

然后,这个最终数据集按照时间顺序排序,从最近的记录开始。

然后选择所需的字段并由语句返回。

如果您有任何问题或意见,请随时发布相应评论。

+0

答案已更正。进行中的解释... – toonice