为什么这个群组不通过查询?

时间:2013-08-29 15:42:15

标签: mysql group-by

我的查询没有正确分组并返回错误的结果,我无法弄清楚问题是什么。

查询如下所示。仅供参考 - 由于我已经删除了查询的所有其他部分以获得最基本的形式(我发现问题),因此我现在需要该组的形式并不明显。

SELECT * FROM (
  SELECT *
  FROM notifications n
  WHERE 1
  --  and group_id = '5b35c8eb075881f8bbdfbcb36b052aa7'
  GROUP BY `from`
) t 
WHERE group_id = '5b35c8eb075881f8bbdfbcb36b052aa7'

问题在于,当我使用put在内部子查询中的位置(当前已注释掉)时,对于这种情况,我最终得到4个结果。 4个结果中的每一个都具有不同的“从”值,因此应单独列出。当我把where子放在子查询的外面时,我得到了3个结果。

为了完整性,表定义是:

CREATE TABLE `notifications` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`mem_id` int(10) unsigned DEFAULT NULL,
`type` varchar(255) NOT NULL,
`from` varchar(255) DEFAULT NULL,
`entry_id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
`table_id` varchar(255) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`emailed` tinyint(1) DEFAULT NULL,
`read` tinyint(1) NOT NULL,
`group_id` char(32) NOT NULL,
PRIMARY KEY (`id`),
KEY `mem_id` (`mem_id`),
KEY `created_at` (`created_at`),
KEY `entry_id` (`entry_id`),
KEY `parent_id` (`parent_id`),
KEY `group_id` (`group_id`)
)

任何可能导致此问题的想法?我完全难过了。在这一点上,我已经准备好将它归因于mysql中的一些错误,但这似乎也不太可能。


更新

我不清楚我的意思是“错误的结果”这个group_id数据集中有7条记录。有2条记录带有唯一的“from”,另外5条记录带有2个“from”id(一个有3个记录,一个有2个)。

在内部执行group by的位置导致了我想要的4条记录。我不关心选择哪一行作为结果,因为我正在做其他总和/计数,我从示例中排除了因为它与问题没有直接关系。

如果我通过两个记录中的一个记录外部组的位置只有一个“来自”,则根本没有返回。
我会尝试用sqlfiddle更新(不知道那个!) - 问题是我正在测试的这个数据库每天被擦除所以我没有原始数据,我会看看我是否可以重现。

更新#2

我注意到在我的问题中,我一直指的是内部和外部的群组 - 群组总是在内部查询上它就是“在哪里”。我试着调整措辞。同样,我不关心为什么我关心地点的位置 - 但在我的最终用例中,我需要在外部进行选择(我正在构建读取/未读取的通知计数,我需要一个计算每个成员和每个消息的总数 - 例如group_id)

sqlfiddle:http://www.sqlfiddle.com/#!2/7d746/5

内部查询的屏幕截图:https://www.evernote.com/shard/s48/sh/e355e96e-e48d-4550-bbaf-ffb18bc0bb9c/08e2454867e00e3a05535303429748f1

查询的屏幕截图,其中outer位于:https://www.evernote.com/shard/s48/sh/60b10427-e417-4196-8b92-7d6d8031d21e/c779bc9c46d23472983ac6fa0d25e42d

使用sqlfiddle我每次都会得到4个结果!这让我更多地认为这是一个服务器问题。我们正在运行MySQL 5.5.28-29.2 Percona Server(GPL),版本rel29.2,修订版360

1 个答案:

答案 0 :(得分:2)

此查询:

  SELECT *
  FROM notifications n
  WHERE 1
  GROUP BY `from`

在ANSI SQL和几乎所有DBMS(oracle,postgres,MS SQL等)中都是错误的
它仅在MySql上运行,因为它们是非标准group by extension
请看这个链接:http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html

Hovever他们警告某事:

  

但是,这主要适用于每个中的所有值   GROUP BY中未命名的非聚合列对于每个列都是相同的   组。服务器可以自由选择每个组中的任何值,所以   除非它们相同,否则所选值不确定

由于此“功能”,您的查询(从select * group by中选择)是不可预测的,结果取决于表中记录的顺序。
看看这个简单的演示:http://www.sqlfiddle.com/#!2/b762e/2
本演示中有两个相同的表,内容相同,唯一的区别是物理行顺序。相同的查询会产生完全不同的结果。



----编辑如何解决这个问题-----

要在查询中解决此问题,只需将两列添加到GROUP BY子句中即可。

select * FROM (
  SELECT * FROM notifications n
  GROUP BY `from`, `group_id`
) x
WHERE group_id = 'A';

select * FROM (
  SELECT * FROM notifications n
  WHERE group_id = 'A'
  GROUP BY `from`, `group_id`
) x

以上两个查询对列fromgroup_id的结果始终相同,其他列(不包括在GROUP BY子句中)可以是随机的。
看看简单的演示 - > http://www.sqlfiddle.com/#!2/5d19b/5