为什么GROUP_BY不返回所需的记录?

时间:2019-01-26 18:16:46

标签: mysql sql

给出以下表格:

invitations (id, created_at, type, email)

给出以下查询:

SELECT DISTINCT email_address
FROM invitations
WHERE type = 'email'
AND date(created_at) in (curdate() - interval 3 day, 
                           curdate() - interval 8 day,
                           curdate() - interval 13 day,
                           curdate() - interval 21 day,
                           curdate() - interval 34 day,
                           curdate() - interval 50 day);

鉴于上面的查询,我得到了几百条记录。我想要的是按电子邮件对记录进行分组,这意味着唯一的电子邮件最多应存在一次。

因此我添加了:

GROUP BY email_address

当我运行查询时,这仅导致2条记录...我使用GROUP BY的方式有误吗?

2 个答案:

答案 0 :(得分:3)

SELECT DISTINCT email ... GROUP BY email毫无意义-使用DISTINCT或GROUP BY来获得相同的结果

如果结果是丢失了两个电子邮件地址,则所选记录集仅包含两个唯一的电子邮件地址

GROUP BY用于汇总某些列组合相同的数据。此组合之外的任何其他列都必须包含在汇总函数中,例如AVG,MAX,SUM等

一个例子:

SELECT city, ethnicity, MAX(age), AVG(salary)
FROM people
GROUP BY city, ethnicity

它将呈现一组独特的城市/种族对,以及该组的最老年龄和平均工资

DISTINCT本质上没有GROUP BY有用,因为它不允许您在其他列上运行聚合函数。它会在所有选定的列中返回唯一的记录集。我认为这很方便:

SELECT DISTINCT city, ethnicity
FROM people

SELECT city, ethnicity
FROM people
GROUP BY city, ethnicity --more to type

答案 1 :(得分:2)

我在这里假设您希望根据包含的created_at字段将记录按组或类似方式串联起来:

SELECT email, GROUP_CONCAT( DISTINCT created_at ORDER BY created_at DESC ) AS list_of_dates FROM invitations GROUP BY email;

产生类似于以下内容的东西:

email              |  list_of_dates  
==========================================================  
jenny@hotmail.com  |  01/26/2019, 01/23/2019  
jonny@gmail.com    |  01/23/2019, 01/18/2019, 01/13/2019  
greg@yahoo.com     |  01/13/2019  

,或者:

SELECT created_at, GROUP_CONCAT( DISTINCT email ORDER BY created_at DESC SEPARATOR '; ' ) AS list_of_dates FROM invitations GROUP BY created_at;

created_at  |  list_of_emails  
====================================  
01/26/2019  |  jenny@hotmail.com  
01/23/2019  |  jenny@hotmail.com; jonny@gmail.com  
01/18/2019  |  jonny@gmail.com  
01/13/2019  |  jonny@gmail.com; greg@yahoo.com  

在GROUP_CONCAT()的上下文中,GROUP BY是可选的,用于将分组进一步划分到单行聚合之外。如果未指定GROUP BY子句,它将把所有内容连接到一行。

  • GROUP_CONCAT()中的DISTINCT关键字必须在串联字段之前,并且只会将唯一字段值返回
  • 可选的ORDER BY跟随串联字段,并且与SELECT查询中的工作相同
  • SEPARATOR也是可选的,但如果也使用,则必须遵循ORDER BY。这使您可以指定用于连接的连接字符串

根据串联的记录数/多长时间,可以通过设置会话变量来调整最大值:

SET SESSION group_concat_max_len=<max length>

无论哪种方式-在您要总结的任何字段上使用GROUP BY并将其他字段包含在GROUP_CONCAT中,希望这会有所帮助。