从其中一些是utf8编码而另一些没有utf8编码的列中选择字符串

时间:2019-03-12 15:57:14

标签: mysql utf-8

数据是国家分区的名称。有些已被保存为utf8,有些则没有。 例如,这就是它们在我表中的样子:

statename

Bocas del Toro
Chiriquí
Coclé
Colón
Darién
Veraguas
Panamá Oeste
Emberá
Kuna Yala
Ngöbe-Buglé

这个问题/答案使我真正接近解决方案: How to fix double-encoded UTF8 characters (in an utf-8 table)

如果我使用: CONVERT(CAST(CONVERT(statename USING latin1) AS BINARY) USING utf8)

statename

Bocas del Toro
Chiriquí
Coclé
Col
Dari
Veraguas
Panam
Emberá
Kuna Yala
Ng

例如,存储为“é”的字符仅在字符串结尾。

该答案中提供的变体形式,

SELECT CASE
    WHEN CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 ) IS NULL
        THEN statename
    ELSE CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 )
END
FROM 

返回了相同的结果,尽管我什至不确定我是否在此选择中正确实现了它。

在这种情况下,我不允许规范化此数据,因此我想选择并获取

Bocas del Toro
Chiriquí
Coclé
Colón
Darién
Veraguas
Panamá Oeste
Emberá
Kuna Yala
Ngöbe-Buglé

这可能吗?

1 个答案:

答案 0 :(得分:0)

SQL_MODE似乎是一个问题。为了使转换失败并返回NULL-STRICT_TRANS_TABLES模式。您可以使用

进行设置
SET SESSION sql_mode = CONCAT('STRICT_TRANS_TABLES,', @@sql_mode);

如果您不想在同一会话中中断其他“有效”查询,则应在获得结果后将其重置:

SET @old_sql_mode = @@sql_mode;
SET SESSION sql_mode = CONCAT('STRICT_TRANS_TABLES,', @@sql_mode);

SELECT COALESCE(
  CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 ), statename
) as statename
FROM yourTable;

SET SESSION sql_mode = @old_sql_mode;

DB Fiddle demo

注意:我对查询进行了一些更改,以使用COALESCE()而不是CASE语句,因此您无需重复转换代码。