当我从ENUM字段尝试select sum
时,我发现了一些奇怪的东西。它为这些值增加了1!我使用的样本表如下所示:
x y
_______
3 | 2
0 | 1
x 和 y 都是ENUM ('0','1','2','3')
我的查询如下:
select sum(x), sum(y), sum(x+y) from myfield
结果是:
5 5 10
这很奇怪。这是否意味着这种行为是否一致?我可以使用类似的东西:
select sum(x - 1), sum(y - 1), sum((x-1)+(y-1)) from myfield
会产生正确的结果,还是这种行为特别是我的数据库服务器特有的?
感谢。
修改
对于那些想知道我为什么使用ENUM的人来说,这是因为我使用的实际字段包含'AR',它不能放入tinyint
。
答案 0 :(得分:3)
由于ENUM
字段实际上只是INT UNSIGNED
,如果对ENUM
使用整数值,它将无法正常工作。例如,您ENUM
的{{1}}内部存储为数字'0'
,而您的1
则存储为数字'1'
。令人惊讶的是,空字符串2
在内部存储为''
。这是一个不能按预期工作的例子:
0
条款mysql> CREATE TABLE enumtest (
-> id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> a ENUM ('0','1','2','3') NOT NULL DEFAULT '0',
-> i int unsigned NOT NULL DEFAULT 0
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO enumtest SET a = 0, i=0;
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'a' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO enumtest SET a = '0', i=0;
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO enumtest SET a = 1, i=1;
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO enumtest SET a = '1', i=1;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT a,0+a,i FROM enumtest;
+---+-----+---+
| a | 0+a | i |
+---+-----+---+
| | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 1 | 1 |
| 1 | 2 | 1 |
+---+-----+---+
4 rows in set (0.00 sec)
mysql> SELECT SUM(a),SUM(0+a), SUM(i) FROM enumtest;
+--------+----------+--------+
| SUM(a) | SUM(0+a) | SUM(i) |
+--------+----------+--------+
| 4 | 4 | 2 |
+--------+----------+--------+
1 row in set (0.00 sec)
强制0+a
为其基础ENUM
值。这相当于UNSIGNED
。
答案 1 :(得分:2)
这是因为在枚举列上执行SUM()
并不会按照您的想法执行操作。为枚举列类型存储的数据是枚举的索引,索引从1开始,而这个索引是mysql将SUM()
显示时,您的表格如下所示:
x y
_______
3 | 2
0 | 1
这显示了您的枚举值 - 您恰好将枚举值定义为数字。您可以将它们定义为例如ENUM ('blue','red','green','yellow')
它看起来像是:
x y
_______________
yellow | green
blue | red
但是,这仅供显示。实际存储在该表的行中的是 枚举中的索引。
列规范中列出的元素被指定为索引 数字,从1开始。
因此,这些索引从1开始。这些基础数据是SUM()和其他聚合函数用于ENUM列。没有隐式转换为枚举值,您也将其定义为数字。
即。存储的数据是这些索引:
x y
_______
4 | 3
1 | 2
虽然它对SUM枚举没有意义,但是当使用SUM()
必须阅读docs。