2010-10-03 63 views
2

我有兩個表:消息(消息用戶張貼),喜歡(用戶和消息之間的多對多關係 - 它表示user1喜歡message5)。SQL - 從兩個表中按列排序

messages 
--------- 
id, id_user, message, created_at 

likes 
----- 
id_user, id_message, created_at 

如果我發送消息,它會進入消息表。如果我喜歡某人的消息,則會在喜歡錶中創建一條新記錄(is_user = me,id_message =我喜歡的消息)。

問題是,我想顯示我的行動=消息的歷史和喜歡在一個列表中排序方式「created_at」

喜歡的東西:

- 1/1/2010 i sent message "aaa" 
- 2/1/2010 i sent message "bbb" 
- 3/1/2010 i liked somebodys's message "ccc" 
- 4/1/2010 i send message "ddd" 

編輯 更糟糕的是,我也想表現出我喜歡的狀態的詳細信息:

- 3/1/2010 i liked somebodys's message **"ccc"** 

如何做到這一點?

回答

6

創建一個名爲'actions'的新表是一個好主意,其中添加消息或喜歡消息的表在此表中被重新記錄,然後通過查詢此表很容易得到您想要的內容。

如果你不能這樣做,那麼你用你現有的模式從每個表UNIONing數據和查詢結果表但作爲created_at指數不能使用它不會被視爲有效:

SELECT * FROM 
(
    SELECT 1 AS type, id, id_user, message, created_at FROM messages 
    UNION ALL 
    SELECT 2 AS type, NULL, id_user, id_message, created_at FROM likes 
) T1 
ORDER BY created_at 

添加連接以獲取有關您喜歡的消息的相關信息,例如消息發件人的用戶名和消息文本。將這些信息轉換爲字符串的任務通常最好在應用程序級完成,以減少數據庫服務器與應用程序之間不必要的數據傳輸。

如果你真的想這樣做,在數據庫中,那麼你可以使用CONCAT構建字符串:

SELECT messagetext 
FROM 
(
    SELECT 
     created_at, 
     CONCAT('I sent message "', message, '"') AS messagetext 
    FROM messages 
    WHERE id_user = 1 
    UNION ALL 
    SELECT 
     likes.created_at, 
     CONCAT('I liked ', messages.id_user ,'\'s message "', messages.message, '"') 
    FROM likes 
    JOIN messages 
    ON likes.id_message = messages.id 
    WHERE likes.id_user = 1 
) T1 
ORDER BY created_at 

結果:

 
I sent message "aaa" 
I sent message "bbb" 
I liked 2's message "ccc" 
I sent message "ddd" 

注意,USER_ID顯示,而不是用戶名。如果你想要用戶名,那麼你還需要加入到用戶表(這個表沒有顯示在你的問題中,但我認爲你有一個)。

+0

感謝馬克。我不需要整個字符串,這是應用程序的責任。我只需要我喜歡的消息的文本,這可以很容易地使用連接完成。 – PetrB 2010-10-03 10:20:11

+0

我決定採用創建新的「動作」表的方式,但我堅持使用數據庫模式。就目前而言,動作表具有列action_id,created_at,discriminator。我還應該在那裏放置什麼以及如何查詢它? – PetrB 2010-10-03 10:43:19

+0

@PetrB:這看起來不錯。您不需要複製此表中其他表中的數據。 – 2010-10-03 10:45:50

0
SELECT .... 
FROM 
(
    SELECT MSGS. 
     ...... 
     MSGS.created_at 
    FROM MSGS 
    WHERE MSG.id_user = me 
    UNION 
    SELECT LIKES. 
     .......... 
     LIKES.created_at 
    FROM MSGS, LIKES 
    WHERE MSGS.id_message = LIKES.id_message 
     AND MSGS.id_user = me 
) A 
ORDER BY A.created_at