1

select sum今日、ENUM フィールドから取得しようとしたときに、奇妙なことを発見しました。値に1を追加していました!私が使用したサンプルテーブルを以下に示します。

x     y
_______
3  |  2
0  |  1

xyはどちらも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

4

2 に答える 2

3

ENUMフィールドは実際には単なる であるためINT UNSIGNED、s に整数値を使用すると、期待どおりに機能しませんENUM。たとえば、あなたENUMの of'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値に強制します。これは と同等CAST(a AS UNSIGNED)です。

于 2013-06-27T21:31:48.417 に答える
2

これはSUM()、enum 列で実行しても、思ったとおりに実行されないためです。列挙列タイプに格納されたデータは、列挙型へのインデックスであり、そのインデックスは 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 列挙型にはあまり意味がありませんが、使用時に mysql が集計するのはこれらのインデックスです。SUM()

ドキュメントは必読です。

于 2013-06-27T21:32:00.337 に答える