2017-05-04 20 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