首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么MySQL将1添加到ENUM值?

为什么MySQL将1添加到ENUM值?
EN

Stack Overflow用户
提问于 2013-06-27 21:19:18
回答 2查看 2.1K关注 0票数 1

今天我在一个ENUM领域尝试select sum时,发现了一些奇怪的东西。它把1加到了值上!下面显示了我使用的示例表:

代码语言:javascript
复制
x     y
_______
3  |  2
0  |  1

X和y都是ENUM ('0','1','2','3')

我的查询如下:

代码语言:javascript
复制
select sum(x), sum(y), sum(x+y) from myfield

结果是:

代码语言:javascript
复制
5    5   10

这很奇怪。这是否意味着这种行为是一致的?我能用这样的东西吗?

代码语言:javascript
复制
select sum(x - 1), sum(y - 1), sum((x-1)+(y-1)) from myfield

哪种行为将产生正确的结果,还是这种行为仅限于我的db服务器?

谢谢。

编辑:对于那些想知道我为什么要使用ENUM的人来说,这是因为我所使用的实际字段包含“AR”,这不能适应tinyint

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-27 21:31:48

由于ENUM字段实际上只是一个数字( INT UNSIGNED ),如果您为ENUMs使用整数值,它将不会像您预期的那样工作。例如,您的ENUM of '0'在内部存储为数字1,而您的'1'存储为数字2。令人惊讶的是,空字符串''在内部存储为0。下面是一个不像预期那样工作的例子:

代码语言:javascript
复制
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值。这相当于CAST(a AS UNSIGNED)

票数 3
EN

Stack Overflow用户

发布于 2013-06-27 21:32:00

这是因为在枚举列上执行SUM()并不像您认为的那样。存储在枚举列类型中的数据是进入枚举的索引,该索引从1开始,它是mysql将SUM()的索引。

当显示时,您的表如下所示:

代码语言:javascript
复制
x     y
_______
3  |  2
0  |  1

这是显示您的枚举值-您只是碰巧将您的枚举值定义为数字。您可以将它们定义为例如ENUM ('blue','red','green','yellow'),它应该是这样的:

代码语言:javascript
复制
x         y
_______________
yellow  |  green
blue    |  red

然而,这只是为了显示。实际上存储在此表的行中的是枚举中的索引。

列规范中列出的元素被指定为索引号,从1开始。

因此,这些索引从1开始。SUM()和其他聚合函数用于ENUM列的正是这些底层数据。不存在对枚举值的隐式转换,您也将枚举值定义为数字。

也就是说,存储的数据是以下索引:

代码语言:javascript
复制
x     y
_______
4  |  3
1  |  2

虽然求和枚举没有什么意义,但是当使用SUM()时,mysql会聚合这些索引

文档是必读的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17353394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档