这是我的示例(适用于Win64(x86_64)的MySQL Ver 14.14 Distrib 5.7.21)
DROP TABLE IF EXISTS t_tt;
CREATE TEMPORARY TABLE t_tt SELECT 1 AS tid,'team 1' AS teamName,111 AS teamData;
INSERT INTO t_tt VALUES(2,'team 2',222);
INSERT INTO t_tt VALUES(3,'team 3',333);
SELECT
tid,
isnull(tid),
IF(isnull(tid),'total',teamName) AS displayName,
SUM(teamData)
FROM t_tt GROUP BY tid WITH ROLLUP;
我认为结果必须是:
+-----+-------------+-------------+---------------+
| tid | isnull(tid) | displayName | SUM(teamData) |
+-----+-------------+-------------+---------------+
| 1 | 0 | team 1 | 111 |
| 2 | 0 | team 2 | 222 |
| 3 | 0 | team 3 | 333 |
| 3 | 1 | total | 666 |
+-----+-------------+-------------+---------------+
实际上,真正的答案是:
+-----+-------------+-------------+---------------+
| tid | isnull(tid) | displayName | SUM(teamData) |
+-----+-------------+-------------+---------------+
| 1 | 0 | team 2 | 111 |
| 2 | 0 | team 3 | 222 |
| 3 | 0 | team 3 | 333 |
| NULL| 0 | team 3 | 666 |
+-----+-------------+-------------+---------------+
我不知道displayName的列为什么以“ team 2”开头,而不是以“ team 1”开头。
最后一行的nonull(tid)应该等于1,但不等于0。
答案 0 :(得分:2)
问题是您正在使用MySQL扩展。 teamName
中有SELECT
,但GROUP BY
中没有SELECT tid, tid is null,
COALESCE(max(teamName), 'total') AS displayName,
SUM(teamData)
FROM t_tt
GROUP BY tid WITH ROLLUP;
。因此,MySQL可以自由地从任何行获取此值。老实说,我认为它必须来自匹配的行。我不完全了解这种行为。
但是,这很容易解决。一种简单的方法就是简单地添加一个聚合函数:
ROLLUP
请注意,对于CREATE TABLE t_tt (
tid int primary key,
teamName varchar(255),
teamData int
);
INSERT INTO t_tt VALUES(1, 'team 1', 111);
INSERT INTO t_tt VALUES(2, 'team 2', 222);
INSERT INTO t_tt VALUES(3, 'team 3', 333);
中的其他行,该值是任意的。
我还发现,如果用主键预先声明了表,则结果是固定的:
.
答案 1 :(得分:1)
最好处理组查询中的所有其他信息,因为未分组的某些列可能具有任意值:
SELECT tid,
isnull(tid),
IF(isnull(tid),'total',teamName) AS displayName,
team_sum
FROM
(
SELECT
tid,
teamName,
SUM(teamData) as team_sum
FROM t_tt
GROUP BY tid WITH ROLLUP
) t
请参见以下Sql Fiddle:http://sqlfiddle.com/#!9/8871cc/9