MySQLのIncorrect string valueのエラーでcharacter_set_databaseを変える方法

MySQLを使っていて、テーブルに行をinsertしようとしたらエラーになりました。

ERROR 1366 (HY000): Incorrect string value: ‘\xE3\x81\xBE\xE3\x81\x90…’ for column ‘name’ at row 1

使っている環境
ubuntu 20.04 LTS
MySQL ver 8.0.30

MySQLの文字コードの問題のようです。「SHOW VARIABLES LIKE 'chara%';」で確認すると、こうなってます。

character_set_database が latin1 になっているからエラーになっているようです。

ここを変えるために /etc/mysql/mysql.conf.d/mysqld.cnf に「character-set-server=utf8mb4」を追記してみたのですが、変わらない。どうやら既存テーブルがあると、その設定のままらしいです。

なので、いったん既存のテーブルを全部削除(drop)しました。

それから以下のコマンドを実行します。

ALTER DATABASE データベース名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

こんな具合です。


mysql> ALTER DATABASE testdb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.04 sec)

もう一度、MySQLの文字コードを確認します。

character_set_database が utf8mb4 になりました。

テーブルをcreateしなおして、エラーとなったinsert文を実行すると行の挿入ができました。

SQLのhaving句の使い方

SQLにはhaving句があるのですが、その使い方を書いてみます。having句は集合関数を使ったときに、集計された結果を条件にすることができます。言葉ではわかりづらいので、例を示します。

注文テーブルがあります。注文されたときの一覧です。1回の注文で1レコードが作成されます。

ここで、注文テーブルからよく売れている(売れた個数が多い)商品を確認するSQLを考えてみると、以下のSQLになります。

select 商品, sum(個数) from 注文
group by 商品;

結果は、こうなります。

この結果からさらに「○個以上売れているもの」を抽出したい場合にhaving句が役に立ちます。例えば、3個以上売れているものを抽出するSQLは以下です。

select 商品, sum(個数) from 注文
group by 商品
having sum(個数) > 2;

結果は、こうなります。

having句は集合関数の結果に対して条件をつけて抽出することができます。集合関数には、count()、sum()、avg()などがあります。

別の例として、注文が2回以上あった商品(注文テーブルに2レコード以上ある)を抽出するSQLは以下です。

select 商品, count(*) from 注文
group by 商品
having count(*) > 1;

結果は、こうなります。

あるテーブルをgroup by句で集計した結果に対して、さらに条件をつけて検索したい場合にhaving句が役に立ちます。

以下の形で覚えてしまいましょう。