Неразрывный пробел, mysql и Like

Есть таблица A и таблица B, в каждой из них есть колонка name (обе utf8_general_ci). Потребовалось найти соответствие name из A в B при том, что A.name содержит B.name (полностью). Казалось бы, что проще -

SELECT A.name, B.name FROM A,B
WHERE A.name LIKE CONCAT ('%',B.name,'%')

* вариант с условием WHERE POSITION (B.name in A.name) давал меньше соответствий

Интересная ситуация - визуально записи отображаются одинаково.. однако при попытке сравнить их, как при помощи оператора = или LIKE результат получается “различным”. При этом проверка “ручками” в браузере (поиск по CTRL+F) словосочетания считает абсолютно одинаковыми..

Мысли-поиски натолкнули на решение.. поскольку UTF-8 - кодировка “хитрая”, то, раз буквы одинаковые (кстати, использовались символы из набора ASCII), значит различие в пробелах :)

В UTF-8 есть несколько видов пробелов.. Неразрывный пробел содержит 2 байта - \xC2\xA0, он же CHAR(194) CHAR(160). По смыслу он очень похож на неразрывный пробел в HTML (чтобы слово не переносилось на следующую строку вместо обычного пробела можно ввести   ).  Поскольку, найденный неразрывный пробел в данном случае скорее мешал, чем приносил пользу, было принято решение заменить его на “обычный”.

Как ввести неразрывный пробел с клавиатуры

Поставить неразрывный пробел в Word (или другой программе) можно при помощи сочетания символов Shift+Ctrl+Пробел. В Word также можно воспользоваться меню “Вставка -> специальный символ-> выбрать из списка неразрывный пробел)

Замена неразрывного пробела

Неразрывный пробел может быть причиной несовпадения одинаковых строк не только в MySQL и других базах данных (MS SQL, Oracle, PqSQL), но и в языках программирования (как в “скриптовых”-интерпретируемых вроде PHP, Ruby, Python, так и в компилируемых)

Заменить неразрывный пробел в MySQL

Для начала, чтобы убедиться, что он присутствует в нужном столбце можно выполнить запрос такого рода:
SELECT name, REPLACE( name, CONCAT( CHAR( 194 ) , CHAR( 160 ) ) , '**' )
FROM `B` WHERE POSITION( CHAR( 194 ) IN name ) >0

Если неразрывные пробелы имеются, заменить их на обычные можно запросом
UPDATE `B` SET name = REPLACE( name, CONCAT( CHAR( 194 ) , CHAR( 160 ) ) , ' ' )
WHERE POSITION( CHAR( 194 ) IN name ) >0;

Возможно, пригодится замена двух подряд идущих пробелов на один
UPDATE `B` SET name = REPLACE( name, ' ', ' ' ) ;

Заменить неразрывный пробел в PHP

$string=str_replace(chr(194).chr(160),'',$string);

Метки: ,

Автор будет признателен, если Вы поделитесь ссылкой на статью, которая Вам помогла:
BB-код (для вставки на форум)

html-код (для вставки в ЖЖ, WP, blogger и на страницы сайта)

ссылка (для отправки по почте)

Добавить комментарий