2011-09-29 133 views
0

在我的基于线程的消息传递系统,表架构是选择行具有不同值的列

> messages table 
id(int auto incr primary key) 
body(varchar) 
time(datetime) 

>message_reference table 
id(int auto incr primary key) 
message_id(forgain key from message table) 
sender 
receiver 

在这里,我要选择被发送到一个新的接收器的第一个消息ID和发件人是登录的用户。

这样做有多个查询和一些代码显然是可能的,但可以用一个查询来完成性能问题吗?

+2

咦?您能否提供一些示例数据和预期结果?什么构成“新”接收器?你如何知道谁登录?当您使用多个查询时,您是否真的看到性能问题? –

+0

为什么你需要两张桌子?它看起来像这将是一个1-1关系,所以你可以把所有东西放在一张桌子上。 – CyberDude

+0

@cyberdude:当用户向多个接收者发送消息时,将它放在一个表中会增加我的db中的冗余度。整个消息需要一次又一次插入。 – Sourabh

回答

1

您可以尝试

编辑:

如果ID是自动递增,则ID也将随时间增加,您可以使用:

SELECT message_reference.message_id, message_reference.receiver, messages.body 
FROM message_reference, messages 
WHERE message_reference.message_id IN (SELECT MIN(message_reference.message_id) 
          FROM message_reference 
          GROUP BY message_reference.receiver) 
AND message_reference.message_id = messages.id AND message_reference.sender = <sender> 
+0

接收者不知道我们,它应该从查询返回。 – Sourabh

+0

如果消息ID是一个自动增加字段,第一个消息会不会有最低的ID?可以做出这样的假设吗? –

+0

不,message_id不是自动增量,消息表中的Id是自动增加的。此外,我不这样做,您可以进行查询,如 SELECT * FROM MESSAGE_REFERENCES WHERE MIN(MESSAGE_ID)AND SENDER = Sourabh

0

这里是我的最佳猜测你想要什么,但是如果你给出了已知的输入,例子数据和期望的输出,那将会更容易。

SELECT 
    MR2.message_id 
FROM (
    SELECT 
     MR.sender, 
     MR.receiver, 
     M.MIN(`time`) AS min_time 
    FROM 
     Message_References MR -- Either use plural names (my personal preference) or singular, but don't mix them 
    INNER JOIN Messages M ON 
     M.id = MR.message_id 
    WHERE 
     MR.sender = <sender> 
    GROUP BY 
     MR.received) SQ 
INNER JOIN Message_References MR2 ON 
    MR2.sender = SQ.sender AND 
    MR2.receiver = SQ.receiver AND 
    MR2.`time` = SQ.min_time 
+0

你能否详细说明你所做的查询?我不明白MR2表是什么? – Sourabh

0
select mr.message_id from 
    message_reference as mr inner join 
    (select mr1.reciever max(m1.time) as time from messages as m1 
     inner join message_reference as mr1 on mr1.message_id = m1.id 
     group by mr1.reciever) as last 
    on mr.reciever = last.reciever and mr.time = last.time 

上reciever和时间加入了“每reciever MAXTIME”表信息参考

0

嗯,我得到了答案,只是一群被查询工作,我想要的方式。我用查询

SELECT SENDER, 
RECEIVER, 
BODY, 
TIME, 
MESSAGE_ID 
FROM MESSAGE_REF JOIN MESSAGE 
ON MESSAGE.ID=MESSAGE_REF.MESSAGE_ID 
ORDER BY 'TIME' GROUP BY RECEIVER` 

谢谢大家的帮忙。

+1

'ORDER BY'子句只能在'GROUP BY'子句之后出现。 此外,即使在交换之后,由于GROUP BY子句将随机选择具有该字段值的任何行,并且该行为是不确定的,所以即使交换后也不会产生正确的结果,因此有时会给出结果想要,有时它可能不是 –

+0

是这样吗?我不知道这个群体的这种行为,直到现在都在产生正确的结果,如果你说的是正确的话,我将不得不寻找其他的方式。 – Sourabh

+2

是的,你可以看看http://stackoverflow.com/questions/1591909/group-by-behavior-when-no-aggregate-functions-are-present-in-the-select-clause –