通过分组选择最大日期?

时间:2015-03-26 16:01:27

标签: mysql select aggregate-functions maxdate

请有人帮忙吗?我把HOURS置于这个愚蠢而愚蠢的问题中。 This stackoverview post完全是我的问题,我尝试过两种建议的解决方案都无济于事。

这是我的具体细节。我从实际数据库中提取了4条记录,并且没有删除任何字段:

master_id   date_sent   type    mailing response
00001   2015-02-28 00:00:00 PHONE   NULL    NULL
00001   2015-03-13 14:45:20 EMAIL   ThankYou.html   NULL
00001   2015-03-13 14:34:43 EMAIL   ThankYou.html   NULL
00001   2015-01-11 00:00:00 EMAIL   KS_PREVIEW  TRUE
00001   2015-03-23 21:42:03 EMAIL   MailChimp Update #2 NULL

(对于列的对齐感到抱歉。)

我想获取每个master_id的最新邮件和date_sent。 (我的摘录只有一个master_id,这个帖子很简单。)

所以我运行这个查询:

SELECT master_id,date_sent,mailing
FROM contact_copy
WHERE type="EMAIL"

并获得预期结果:

master_id   date_sent   mailing         
1   3/13/2015   14:45:20    ThankYou.html       
1   3/13/2015   14:34:43    ThankYou.html       
1   1/11/2015   0:00:00 KS_PREVIEW      
1   3/23/2015   21:42:03    MailChimp   Update  #2

但是,当我添加这个简单的聚合以获取最新日期时:

SELECT master_id,max(date_sent),mailing
FROM contact_copy
WHERE type="EMAIL"
group BY master_id
;

我得到了一个意想不到的结果:

master_id   max(date_sent)  mailing
00001   2015-03-23 21:42:03 ThankYou.html

所以我的问题是:为什么它会返回错误的邮件?

它让我疯了!感谢。

顺便说一句,我不是开发人员,如果我违反了一些礼仪规则,那就很抱歉。 :)

2 个答案:

答案 0 :(得分:2)

那是因为当你使用GROUP BY时,所有列都必须是聚合列,而邮件不是其中之一..

您应该使用子查询或联接来使其正常工作

SELECT master_id,date_sent,mailing
FROM contact_copy cc
JOIN 
( SELECT master_id,max(date_sent)
  FROM contact_copy
  WHERE type="EMAIL"
  group BY master_id
 ) result
ON cc.master_id= result.master_id AND cc.date_sent=result.date_sent

答案 1 :(得分:0)

由于GROUP BY功能的MySQL特定扩展,您获得了“意外”结果。根据MySQL参考手册,您实际可以获得预期的结果。

参考:https://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html


其他数据库引擎会将您的查询拒绝为无效...“non-aggregate expressions included in the SELECT list not included in the GROUP BY”的错误。)

如果我们在SQL模式中包含ONLY_FULL_GROUP_BY,我们可以让MySQL像其他数据库一样运行(并为该查询返回错误)。

参考:https://dev.mysql.com/doc/refman/5.5/en/sql-mode.html#sqlmode_only_full_group_by


要获得您正在寻找的结果......

如果(master_id,type,date_sent)中的contact_copy元组是唯一的(即,对于master_idtype的给定值,则不存在{重复“值{ {1}}),我们可以使用JOIN操作来检索指定的结果。

首先,我们编写一个查询来获取给定date_sentdate_sent的“最大”master_id。例如:

type

要检索与“maximum”SELECT mc.master_id , mc.type , MAX(mc.date_sent) AS max_date_sent FROM contact_copy mc WHERE mc.master_id = '0001' AND mc.type = 'EMAIL' 关联的整行,我们可以将该查询用作内联视图。也就是说,将查询文本包装在parens中,分配一个别名,然后引用它就好像它是一个表,例如:

date_sent

请注意,如果有多个行具有相同的SELECT c.master_id , c.date_sent , c.mailing FROM ( SELECT mc.master_id , mc.type , MAX(mc.date_sent) AS max_date_sent FROM contact_copy mc WHERE mc.master_id = '0001' AND mc.type = 'EMAIL' ) m JOIN contact_copy c ON c.master_id = m.master_id AND c.type = m.type AND c.date_sent = m.max_date_sent master_idtype值,则可能会返回多行。您可以添加date_sent子句以保证只返回一行;返回哪些行是不确定的,在LIMIT子句之前没有LIMIT 1子句。