【问题标题】:Can I safely use two MAX calls in a SQL query我可以在 SQL 查询中安全地使用两个 MAX 调用吗
【发布时间】:2013-05-06 00:58:23
【问题描述】:

我有一个包含数十万条目的表,我正在尝试使用查询来获取特定接收者 ID 的结果集,并按发送者 ID 对它们进行分组。我当前的 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 调用有什么问题吗?如果是这样,还有什么选择?

【问题讨论】:

  • 不,这很好。但是,请意识到您可以在 select 子句中包含 Receiver_id 而不按 receiver_id 进行分组的唯一原因是因为 where 子句将查询限制为只有一个 receiver_id [5] 的值。如果结果中有多个receiver_id 值,您必须同时按receiver_id 分组,或者不将其包含在结果中
  • 请注意,receiver_id 将从适合该 group by 的行之一中“随机”选择,因为它不是聚合,也不会在聚合/group by 中分组询问。 (只有 MySQL 允许你这样做,所有其他 SQL 风格都会阻止这种无意义的查询。)
  • 请注意,不能保证两个 MAX() 值都引用同一行。
  • @Pataswhu,不,他还将输出限制为仅receiver_id = 5。这完全没问题。
  • @Paul 如果你希望它是同一行,那么 Max(Id) 和 Max(date) 的含义变得不清楚,在一行中,每个只有一个值这些列。您希望使用什么规则来识别这一行?身份证?还是日期?你不能同时使用它们,因为它们可能指向不同的行。

标签: mysql sql groupwise-maximum


【解决方案1】:

我不太了解您的结构(例如,此示例假定可以将唯一键强加给 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;

【讨论】:

  • 这似乎工作得很好......我所要做的就是追加:'AND x.receiver_id = 5'
【解决方案2】:

基于 cmets 你想要的是:

' 唯一的 [特定接收者 ID 的发送者 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,你的意思是 ' 特定接收者 ID 的唯一发送者 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

【讨论】:

  • 这看起来不对。哪一部分保证唯一的 sender_ids?
  • 当我阅读 Paul 的评论时,他不想要唯一的发件人 ID,他想要所有 senderIds 具有单个接收者的最新发送日期。但如果你是对的,我编辑了答案以包括两种可能性
猜你喜欢
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-10
相关资源
最近更新 更多