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

Jos*_*uez 6 php mysql

这个问题与两种不同类型的编码之间PHP字符串比较并不重复,因为我的问题需要SQL解决方案,而不是PHP解决方案.


背景 ►有一个博物馆有两个数据库,engine=INNODB charset=utf8 collate=utf8_unicode_ci两个不同的PHP系统使用相同的字符集和校对().每个PHP系统以不同的方式存储相同的数据,下一个图像是一个例子:

在此输入图像描述

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

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

问题 ►有像什么utf8_encodeutf8_decode在MYSQL,让我来匹配相当于两列的值?任何其他建议将是受欢迎的.

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

            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'
Run Code Online (Sandbox Code Playgroud)

这条线ON venta_en_linea.ventas_detalle.tipo_boleto_tipo = boleteria.tipos_boletos.tipo永远不会起作用,因为两个值都不同("Niños"vs"Niños").

Mat*_*t S 6

写入数据库的应用程序似乎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
Run Code Online (Sandbox Code Playgroud)

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

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