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

时间:2017-09-11 16:08:23

标签: php mysql

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

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

enter image description here

这种方式已经存储了大量数据,并且两个系统都运行正常,因此我无法更改PHP编码或数据库。一个系统处理票房的销售,另一个处理来自网站的销售。

问题►我需要将右列(tipo_boleto_tipo)与左列(tipo)进行比较,以获取左侧另一列中的值table(在图像中看不见),但我没有得到任何结果,因为相同的值存储不同,例如,当我搜索“Niños”时找不到它,因为它被存储为“Niños”(“children”在西班牙语中)。我试图通过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”vs“Niños”)。

1 个答案:

答案 0 :(得分:3)

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

我无法从你的例子中准确地说出错误的字符集是什么,但假设它是拉丁语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表添加新列和触发器,在添加或编辑记录时即时转换。