鉴于下面的SQL代码:
create table A(a integer, b integer, c double);
insert into A(a, b, c)
values
(0, 0, 1.1),(1, 0, 1.2),(2, 0, 1.3),
(0, 1, 1.4),(1, 1, 1.5),(2, 1, 1.6),
(0, 2, 1.7),(1, 2, 1.8),(2, 2, 1.9),
(0, 0, 1.9),(1, 0, 1.8),(2, 0, 1.7),
(0, 1, 1.6),(1, 1, 1.5),(2, 1, 1.4),
(0, 2, 1.3),(1, 2, 1.2),(2, 2, 1.1)
mysql> select * from A where a = 0;
+------+------+------+
| a | b | c |
+------+------+------+
| 0 | 0 | 1.1 |
| 0 | 1 | 1.4 |
| 0 | 2 | 1.7 |
| 0 | 0 | 1.9 |
| 0 | 1 | 1.6 |
| 0 | 2 | 1.3 |
+------+------+------+
mysql> select * from A where a = 0 group by b;
+------+------+------+
| a | b | c |
+------+------+------+
| 0 | 0 | 1.1 |
| 0 | 1 | 1.4 |
| 0 | 2 | 1.7 |
+------+------+------+
3 rows in set (0.00 sec)
为什么3行?我认为两个查询都应返回相同的结果,因为存在唯一的c组合。
另外
mysql> select *, sum(c) from A group by b;
+------+------+------+--------+
| a | b | c | sum(c) |
+------+------+------+--------+
| 0 | 0 | 1.1 | 9 |
| 0 | 1 | 1.4 | 9 |
| 0 | 2 | 1.7 | 9 |
+------+------+------+--------+
3 rows in set (0.00 sec)
总和似乎是所有行的总和而不是分组的总和
为什么我会看到这种奇怪的行为?
答案 0 :(得分:4)
在标准SQL中,包含GROUP BY子句的查询无法引用 选择列表中未分配的非聚合列 GROUP BY子句。例如,此查询在标准SQL中是非法的 因为选择列表中的名称列不会出现在 GROUP BY:
SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid
GROUP BY o.custid;
要使查询合法,必须从中省略name列 选择列表或在GROUP BY子句中命名。
MySQL扩展了GROUP BY的使用,以便选择列表可以引用 未在GROUP BY子句中命名的非聚合列。
<强>参考文献:强>
答案 1 :(得分:2)
Mysql是为数不多的(有没有其他?)数据库之一,允许这样的“非法”SQL,其中group by
在所选的其他列上没有聚合函数。
不是抛出错误,而是返回符合条件的第一个行,无论该分组的值是什么值。