Игнорировать акценты в «где»

17

В нашей базе данных есть несколько записей с caron / hatschek. Теперь наши пользователи хотят найти записи, включая caron / hatschek, когда они ищут записи без. Я покажу это на простом примере:

В нашей базе данных есть запись (контакт с именем)

Millière

так что это имя правильно в стране, в которой человек живет.

В нашей стране у нас нет символов с caron / hatschek, поэтому наш пользователь ищет Milliere. Никаких результатов не получается, так как èявно не совпадает e.

Я понятия не имею , как это может быть реализовано , как é, è, êи многое другое доступны (и это только пример для письма e...).

(Другой способ был бы намного проще, поскольку я мог бы просто заменить все буквы на caron / hatschek на базовые. Очевидно, что наши пользователи хотят иметь правильную версию имени в базе данных, а не поврежденную.)

ЛЮМО
источник
Обратите внимание, что буква «ё» не имеет карона / хачека, у нее серьезный акцент; caron / hacek будет "е". Вы имеете в виду «персонажей с акцентами» или что-то в этом роде? Или вы конкретно имеете в виду акцент caron / hacek?
psmears
Я имею в виду любые символы со «знаками» (извините, я не знаю, какое у него настоящее имя.
lumo

Ответы:

31

Эта проблема может быть решена с использованием сортировки без учета акцента .

Ваша база данных, вероятно, использует сопоставление AS (Accent Sensitive), поэтому по умолчанию она будет искать точное совпадение, включая акценты.

Вы можете указать предложению WHERE использовать другое сопоставление, отличное от значения по умолчанию для базы данных, указав сопоставление со сравнением.

В этом dbfiddle я создал пример с использованием параметров сортировки LATIN1, но вы можете использовать тот же подход, что и при использовании параметров сортировки, просто изменив AS на AI для параметров сортировки, используемых в данный момент вашим столбцом.

Используйте сопоставление нечувствительного к акценту, совпадающее с тем, которое использует столбец. Например, если столбец использует SQL_Latin1_General_CP1_CI_AS, использует SQL_Latin1_General_CP1_CI_AIи не использует Latin1_General_CI_ASили не использует Latin1_General_100_CI_ASлюбые из этих двух вариантов, так как поведение сопоставлений, отличных от SQL_, будет отличаться в большей степени, чем просто нечувствительность к акценту, и пользователи могут этого не ожидать.

Вы можете проверить текущую сортировку в sys.columns.

CREATE TABLE testaccent (name nvarchar(50));
GO
INSERT INTO testaccent (name) VALUES ('Millière') , ('Milliere');
GO
-- returns Miliere
SELECT * FROM testaccent WHERE name = 'Milliere';

-- returns both
SELECT * FROM testaccent WHERE name='Milliere' COLLATE Latin1_General_CI_AI

--only returns Miliere
SELECT * FROM testaccent WHERE name='Milliere' COLLATE Latin1_General_CI_AS

Прочтите Использование SQL Server Collation для получения дополнительной информации.

С другой стороны, вы, вероятно, захотите, чтобы сортировка использовала это сопоставление (как peufeu отметил в комментариях), чтобы гарантировать, что "é" сортирует с "e". В противном случае тот, кто разбивает результаты на страницы в алфавитном порядке, будет удивлен, если не найдет «é» там, где они ожидают его, но если вы хотите только коснуться этого запроса, вы можете добавить к нему и COLLATEпредложение ORDER BY.

Как отметил Соломон Руцки в комментариях, если это затрагивает только один или несколько столбцов, другой вариант - создать непостоянный вычисляемый столбец, который просто повторяет столбец «name» и обеспечивает сортировку без учета акцента, а затем индексировать вычисленный колонка. Это позволяет избежать сканирования, вызванного изменением параметров сортировки в запросе. Затем запрос необходимо отфильтровать по новому столбцу.

Что-то вроде:

ALTER TABLE 
dbo.[table_name] ADD [SearchName] datatype_of_name_column 
AS ([Name] COLLATE LATIN1_GENERAL_100_CI_AI)); 

CREATE INDEX [IX_table_name_SearchName] 
ON dbo.[table_name] ([SearchName] ASC);

Или вы можете также создать представление вместо добавления вычисляемого столбца (как предпочитает jyao ).

Том V - Команда Моника
источник
1
Том: Я хотел бы отметить (и выделить), что они должны использовать нечувствительную к акценту версию сопоставления, которую использует столбец (сопоставление по умолчанию для базы данных, упомянутое в пункте 3, не относится к этому вопросу). Если столбец используется SQL_Latin1_General_CP1_CI_AS, использование SQL_Latin1_General_CP1_CI_AIи не Latin1_General_CI_ASили Latin1_General_100_CI_ASили любой из вариантов этих двух с момента поведения непредставленных SQL_сортировки будет отличаться большим количеством способов , чем просто акцентом-нечувствительность, и что не может ожидать от пользователей. Сопоставление найдено в sys.columns.
Соломон Руцкий
@SolomonRutzky хорошее предложение
Том V - Команда Моника