2010-10-03 114 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