比较使用不同编码存储的相同值

Posted

技术标签:

【中文标题】比较使用不同编码存储的相同值【英文标题】:Compare same values stored with different encodings 【发布时间】:2018-02-19 22:44:05 【问题描述】:

此问题与php string comparison between two different types of encoding 不重复,因为我的问题需要 SQL 解决方案,而不是 PHP 解决方案。


上下文 ► 有一个博物馆,有两个数据库,两个不同的 PHP 系统使用相同的字符集和排序规则 (engine=INNODB charset=utf8 collate=utf8_unicode_ci)。每个 PHP 系统以 不同 方式存储 相同 数据,下一张图片就是一个例子:

已经有大量数据以这种方式存储,并且两个系统都运行良好,所以我无法更改 PHP 编码或数据库。一个系统处理票房的销售,另一个处理网站的销售。

问题 ► 我需要将右列 (tipo_boleto_tipo) 与左列 (tipo) 进行比较,以获取左表另一列中的值(在图像),但我没有得到任何结果,因为相同的值存储不同,例如,当我搜索“Niños”时,它没有找到,因为它被存储为“Niños”(西班牙语中的“儿童”)。我尝试通过 PHP 使用 utf8_encodeutf8_decode 来实现,但速度慢得让人无法接受,所以我认为最好只使用 SQL 来实现。这些数据将用于不同时间段的销售(票房和互联网)的统一报告,并且必须比较数十万行,这就是 PHP 如此缓慢的原因。

问题mysql 中是否有类似utf8_encodeutf8_decode 的东西可以让我匹配两列的等效 值?欢迎任何其他建议。

接下来是我当前的代码(没有结果):

            DATABASE    TABLE      COLUMN
               ▼          ▼          ▼
    SELECT boleteria.tipos_boletos.genero            ◄ DESIRED COLUMN.
      FROM boleteria.tipos_boletos                   ◄ DATABASE WITH WEIRD CHARS.
INNER JOIN venta_en_linea.ventas_detalle             ◄ DATABASE WITH PROPER CHARS.
        ON venta_en_linea.ventas_detalle.tipo_boleto_tipo = boleteria.tipos_boletos.tipo
     WHERE venta_en_linea.ventas_detalle.evento_id='1'
       AND venta_en_linea.ventas_detalle.tipo_boleto_tipo = 'Niños'

ON venta_en_linea.ventas_detalle.tipo_boleto_tipo = boleteria.tipos_boletos.tipo 行永远不会起作用,因为这两个值不同(“Niños”与“Niños”)。

【问题讨论】:

问题还没有结束,只有一个结束投票。我同意,这不是那个的副本 您的问题从未关闭,因此 Possible duplicate[...]。我撤回了我的近距离投票并 +1,因为这个问题似乎是独一无二的并且很好地提出。 @JoseManuelAbarcaRodríguez 你试过使用COLLATE吗?除非我误解了 COLLATE 这才是你需要的。 @Script47,数据库和表都有相同的排序规则 = utf8_unicode_ci。 【参考方案1】:

似乎写入boleteria 数据库的应用程序未存储正确的UTF-8。数据库列字符集是指 MySQL 如何解释字符串,但您的应用程序仍然可以写入其他字符集。

我无法从您的示例中确切知道不正确的字符集是什么,但假设它是 Latin-1,您可以将其转换为 latin1(使其“正确”),然后将其转换回“实际”utf8:

SELECT 1
FROM tipos_boletos, ventas_detalle 
WHERE CONVERT(CAST(CONVERT(tipo USING latin1) AS binary) USING utf8) 
      = tipo_boleto_tipo COLLATE utf8_unicode_ci

我经常在 PHP 应用程序中看到这种情况,这些应用程序从一开始就没有仔细编写以使用 UTF-8 字符串。如果您发现性能太慢并且需要频繁转换,并且您没有机会更新写入数据不正确的应用程序,您可以添加一个新列和触发器到tipos_boletos 表并即时转换随着记录的添加或编辑。

【讨论】:

有效,有效,马特,你是最棒的!!!只是为了这个精彩答案的未来访问者,我收到错误“非法混合排序规则......”,我修复了在where 末尾添加COLLATE utf8_unicode_ci(从***.com/a/11770234/3298930 窃取)。非常感谢你,伙计!

以上是关于比较使用不同编码存储的相同值的主要内容,如果未能解决你的问题,请参考以下文章

当我在存储过程中使用相同的公式计算日期时,日期值格式不同 - 雪花

vb基础知识

反射比较两个对象属性名相同值不同

使用相同容器的不同加密值

使用不同编码编码的两个不同字符串可以具有相同的字节序列吗?

数据链路层