2013-05-11 27 views
4

我有一个包含数十万条目的表,我试图使用查询来获取特定receiver_id的结果集,并通过sender_id对它们进行分组。我目前的SQL查询工作正常,但我想知道在语句中使用两个MAX调用是否会有任何潜在的问题。它看起来像这样:我可以安全地在SQL查询中使用两个MAX调用

SELECT MAX(id) as id, sender_id, receiver_id, MAX(date) as date 
FROM  messages 
WHERE receiver_id=5 and belong_to=5 
GROUP BY sender_id 

表日期如下:

id sender_id receiver_id content date     belong_to   
-- --------- ----------- ------- ------------------- --------- 
1 5   7   test 2013-03-11 10:33:54 7 
2 5   7   test 2013-03-11 10:33:54 5 
3 13  7   test 2 2013-03-13 12:01:36 7 
4 13  7   test 2 2013-03-13 12:01:36 13 
5 5   7   test 3 2013-03-14 09:15:37 7 
6 5   7   test 3 2013-03-14 09:15:37 5 
7 25  5   data1 2013-03-15 11:01:36 5 
8 25  5   data1 2013-03-15 11:01:36 25 
9 16  5   data2 2013-03-17 09:17:17 5 
10 16  5   data2 2013-03-17 09:17:17 16 
11 25  5   data3 2013-04-05 09:17:17 5 
12 25  5   data3 2013-04-05 09:17:17 16 

从我查询的输出是这样的:

id sender_id receiver_id date    
-- --------- ----------- ------------------- 
9 16  5   2013-03-17 09:17:17 
11 25  5   2013-04-05 09:17:17 

是否有使用该查询的任何问题MAX呼叫?如果是的话,还有什么选择?

+1

不,这很好。但是,要明白,只要在select子句中包含'Receiver_id'而不用'receiver_id'进行分组,就是因为where子句将查询仅限制为'receiver_id'的一个值[5]。如果结果中有多个receiver_id值,您必须也可以用'receiver_id'进行分组,或者不将其包含在结果中 – 2013-05-11 13:22:59

+2

请注意,'receiver_id'将从适合的行中随机选择在该群组之下,因为它不是一个聚合,并且它不通过查询聚合到一个聚合/群组中。 (只有MySQL会让你这么做,所有其他的SQL风格都会阻止这种毫无意义的查询。) – Patashu 2013-05-11 13:23:35

+0

不,使用多个'MAX'聚合肯定是有用的。尽管出于可移植性考虑,您可能希望将“GROUP BY”更改为“GROUP BY sender_id,receiver_id”。 – 2013-05-11 13:23:47

回答

3

我不太明白你的结构(因此,例如,本例假设一个唯一的密钥可以在sender_id, receiver_id, date, belong_to实行的),但我怀疑你想这样的事情。必要时按用户过滤。

SELECT x.* 
    FROM messages x 
    JOIN 
    (SELECT sender_id 
      , receiver_id 
      , MAX(date) max_date 
     FROM messages 
     GROUP 
      BY receiver_id 
      , sender_id 
    ) y 
    ON y.sender_id = x.sender_id 
    AND y.receiver_id = x.receiver_id 
    AND y.max_date = x.date 
WHERE x.belong_to = x.receiver_id; 
+0

这似乎是工作很好......我所要做的只是追加:'AND x.receiver_id = 5' – Paul 2013-05-11 14:03:37

0

基于评论你想要的是:

独特的[sender_ids的与最新的条目(日期)每个[接收者]特定receiver_id列表“如果你的意思是所有发件人谁有最新的入境日期为单个接收器,然后:

Select * From Messages m 
Where date = (Select Max(date) From messages 
       Where receiver_id = m.receiver_id) 
    And receiver_id = 5 -- add this if you only want results for one receiver_id 

如果OTOH,你的意思是 'sender_ids的唯一列表与最新的每个[接收者发送组合]条目(日期)特定receiver_id ', 然后 为此

Select * From Messages m 
Where date = (Select Max(date) From messages 
       Where Sender_id = m.Sender_id 
        And receiver_id = m.receiver_id) 
    And receiver_id = 5 -- add this if you only want results for one receiver_id 
+0

这看起来不对。哪一部分保证唯一的sender_ids? – JJJ 2013-05-11 13:38:09

+0

这只是返回一个条目的最新日期... – Paul 2013-05-11 13:38:48

+0

当我读保罗的评论,他不想要唯一的发件人ID,他希望所有'senderId's有一个接收器的最新发送日期。但偶然你是对的,我编辑的答案包括两种可能性 – 2013-05-11 13:43:44

相关问题