0

请有人帮忙吗?我已经在这个愚蠢的问题上投入了 HOURS 时间。这篇 stackoverview 帖子完全是我的问题,我尝试了两种建议的解决方案都无济于事。

这是我的细节。我从我的实际数据库中提取了 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

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

这让我疯了!谢谢。

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

4

2 回答 2

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
于 2015-03-26T16:08:50.060 回答
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”的错误。)

ONLY_FULL_GROUP_BY如果我们包含在 SQL 模式中,我们可以让 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将不会有 的“重复”值date_sent),我们可以使用 JOIN 操作来检索指定的结果。

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

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'

要检索与该“最大”关联的整行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_id,则可能会返回多行。您可以添加一个子句来保证您只返回一行;返回哪些行是不确定的,在 LIMIT 子句之前没有子句。typedate_sentLIMIT 1ORDER BY

于 2015-03-26T16:21:09.093 回答