2017-04-25 28 views
0

我有一個聊天系統,我想要顯示最近一小時內發送的消息,但無論如何顯示最後20條消息很久以前他們被送去了。如果在過去一小時內沒有記錄,可獲取上一小時內的記錄或最後20項內容

有沒有一種方法可以做到這一點in.a SQL查詢?

CREATE TABLE IF NOT EXISTS `chat` (
    `id`  INT(11) UNSIGNED                   NOT NULL AUTO_INCREMENT, 
    `user_id` INT(11) UNSIGNED                   NOT NULL, 
    `item_id` INT(11) UNSIGNED                   NOT NULL, 
    `message` TEXT                      NOT NULL, 
    `recipient` INT(11)                      NOT NULL DEFAULT '0', 
    `type`  ENUM ('message', 'announcement') NOT NULL DEFAULT 'message', 
    `channel` ENUM ('general', 'private')            NOT NULL DEFAULT 'general', 
    `posted` DATETIME                     NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`), 
    KEY `posted` (`posted`), 
    KEY `type` (`type`), 
    KEY `channel` (`channel`), 
    KEY `recipient` (`recipient`) 
) 
    ENGINE = MyISAM 
    DEFAULT CHARSET = `utf8` 
    AUTO_INCREMENT = 2; 
+0

顯示錶格的模式。 –

+0

@SloanThrasher對不起,添加了模式。只是沒想到這會有很大的幫助。 – Draven

+0

一個簡單的'ORDER BY posted',限制爲20會做 –

回答

2

這應該做的伎倆:

(
    select * from chat 
    where timestamp > DATE_SUB(now(), interval 1 hour) 
) 
union 
( 
    select * from chat order by posted desc limit 20 
) 
order by posted 

說明:

  • 它選擇在最後一個小時的所有消息。
  • 它還選擇的最後20條消息,作爲一個單獨的查詢(20條快)
  • 工會合並兩個結果,並且如果去除雙打兩個

之間有重疊,所以,當在過去一小時內沒有數據,您仍然可以獲得最近20個帖子。如果在過去一小時內有大量數據,您將獲得所有這些數據。

+0

這太棒了!謝謝 – Draven

1

試試這個:

SELECT * 
FROM `chat` 
ORDER BY `posted` DESC 
LIMIT 0,20; 

它會列出最後20行(日期/時間)。由於您希望在最近一小時內沒有足夠的時間進行舊聊天,因此您無需擔心聊天的年齡。

以下內容未經測試,可能有語法錯誤,因此您可能需要使用它。

SELECT * 
FROM `chat` 
WHERE DATE_ADD(a.`posted` interval 1 hour) <= NOW() 
UNION 
(
    SELECT * 
    FROM `chat` 
    WHERE a.posted > DATE_SUB(NOW(), interval 1 hour) 
    AND (SELECT count(*) FROM `chat` WHERE a.posted <= DATE_SUB(NOW(), interval 1 hour)) < 20 
    ORDER BY `posted` DESC 
    LIMIT 0,20) 
ORDER BY `posted` DESC 

它應該只添加超過最後一小時的帖子,當最近一小時的帖子少於20個時。

+0

這不會顯示只有最後20條消息嗎?如果在過去一小時內發送了100封郵件會怎麼樣?我想顯示全部100條消息。 – Draven

+0

是的,只顯示最後20個。我可以重寫,在最後一小時內顯示所有內容,並在一個小時內顯示最後20個內容,並且可以在代碼中忽略它們,當最後足夠時調用查詢小時。 –

+0

只是提示:不要做'DATE_ADD(a.posted interval 1小時)<= NOW()'。相反,請執行'a.posted> DATE_SUB(NOW(),間隔1小時)'。它會產生相同的結果,但運行速度要快得多。您的版本需要爲表中的每一行添加一小時,這意味着也不會使用任何索引。這會慢很多。在大桌上它將是一個不同的世界。 –

相關問題