Вы можете добавить новое сопоставление в ваш запрос выбора, чтобы найти регистр с учетом или без учета.
-- Case sensitive exampleSELECT*FROMTABLEWHERE Name collate SQL_Latin1_General_CP1_CS_AS like'%hospitalist%'-- Case insensitive exampleSELECT*FROMTABLEWHERE Name collate SQL_Latin1_General_CP1_CI_AS like'%hospitalist%'
Просто помните о проблемах производительности, которые могут возникнуть. Вам нужно будет сканировать кластерный индекс, чтобы настроить / найти значения при выполнении сопоставления. То, как вы пишете LIKEкусок, также делает запрос несортируемым.
@stom Есть два метода. Либо а) Перенесите вопросы производительности на время обработки, а не selectвремя. Вы можете сделать это, создав новый столбец с преобразованным подмножеством данных, а затем индексировать его, как правило, в периоды, когда вы запускаете ETL. Это будет стоить содержание и не очень хороший метод. Б) Вы можете сделать поиск по запросу спорным или раздражительным. Изменение запроса, чтобы быть SELECT * FROM TABLE WHERE VALUE LIKE %hospitalistили SELECT * FROM TABLE WHERE VALUE LIKE hospitalist%будет работать. Кроме того, вы смотрите на оборудование или функции, чтобы увеличить скорость при плохом дизайне.
Шаулинатор
14
Хотя вы можете использовать скалярную функцию, такую как UPPER или LOWER, и вы можете повторно сопоставить столбец, чтобы он больше не учитывал регистр, все эти подходы требуют преобразования данных в базовые данные, которые никогда не позволят выполнить поиск по индексу. Вы также ведете свой LIKE с помощью подстановочного знака, так что в любом случае это не так важно для вас в этом сценарии, но если вы когда-нибудь хотели найти эффективный способ поиска левой части строки И включить оптимизатор для поиска по индексу вы можете указать строку в скобках ([]) следующим образом:
SELECT*FROMTABLEWHERE Name LIKE'[hH][oO][sS][pP][iI][tT][aA][lL][iI][sS][tT]%'
CREATETABLE#tmp_cohellation_fun(
ID INT IDENTITY(1,1)PRIMARYKEYCLUSTERED, myValue VARCHAR(50)COLLATE SQL_Latin1_General_CP1_CS_AS)-- Garbage values to represent data you don't wantINSERTINTO#tmp_cohellation_funSELECT CAST(NEWID()AS VARCHAR(50))FROM master.sys.configurations t1CROSSJOIN master.sys.configurations t2CROSSJOIN master.sys.configurations t3;-- Sprinkle a little bit of good dataINSERTINTO#tmp_cohellation_fun(myValue)VALUES('Apple'),('apple')-- Another healthy helping of garbage that we don't care aboutINSERTINTO#tmp_cohellation_funSELECT CAST(NEWID()AS VARCHAR(50))FROM master.sys.configurations t1CROSSJOIN master.sys.configurations t2CROSSJOIN master.sys.configurations t3;-- Some more good dataINSERTINTO#tmp_cohellation_fun(myValue)VALUES('aPple'),('APPLE'),('APple')-- Final insert of garbage that we don't care aboutINSERTINTO#tmp_cohellation_funSELECT CAST(NEWID()AS VARCHAR(50))FROM master.sys.configurations t1CROSSJOIN master.sys.configurations t2CROSSJOIN master.sys.configurations t3;-- Create a nonclustered rowstore indexCREATEINDEX ix_myValue ON#tmp_cohellation_fun (myValue);SETSTATISTICSXMLON;-- Seek, but incorrect resultsSELECT*FROM#tmp_cohellation_funWHERE myValue LIKE'apple%';-- Scan, with correct resultsSELECT*FROM#tmp_cohellation_funWHERE myValue COLLATE SQL_Latin1_General_CP1_CI_AS LIKE'apple%';-- Seek, with correct resultsSELECT*FROM#tmp_cohellation_funWHERE myValue LIKE'[aA][pP][pP][lL][eE]%';SETSTATISTICSXMLOFF;DROPTABLEIFEXISTS#tmp_cohellation_fun
Любить это. Это вне меня, почему SQL не может просто изящно отступить, как это, когда вы говорите, что сортировка от чувствительного к регистру до нечувствительного к регистру, когда у вас есть два одинаковых в противном случае сопоставления. Я понимаю, почему ты не можешь пойти другим путем. Во всяком случае, это хорошая вещь.
Джон Лейдгрен
13
И это, и COLLATEответ будут влиять на производительность, поскольку они делают запрос не SARGable , но самый простой способ сделать это (как предложил Эдгар в комментарии):
select
время. Вы можете сделать это, создав новый столбец с преобразованным подмножеством данных, а затем индексировать его, как правило, в периоды, когда вы запускаете ETL. Это будет стоить содержание и не очень хороший метод. Б) Вы можете сделать поиск по запросу спорным или раздражительным. Изменение запроса, чтобы бытьSELECT * FROM TABLE WHERE VALUE LIKE %hospitalist
илиSELECT * FROM TABLE WHERE VALUE LIKE hospitalist%
будет работать. Кроме того, вы смотрите на оборудование или функции, чтобы увеличить скорость при плохом дизайне.Хотя вы можете использовать скалярную функцию, такую как UPPER или LOWER, и вы можете повторно сопоставить столбец, чтобы он больше не учитывал регистр, все эти подходы требуют преобразования данных в базовые данные, которые никогда не позволят выполнить поиск по индексу. Вы также ведете свой LIKE с помощью подстановочного знака, так что в любом случае это не так важно для вас в этом сценарии, но если вы когда-нибудь хотели найти эффективный способ поиска левой части строки И включить оптимизатор для поиска по индексу вы можете указать строку в скобках ([]) следующим образом:
Этот пример ( ссылка на dbfiddle здесь ) лучше показывает, что я имею в виду:
источник
И это, и
COLLATE
ответ будут влиять на производительность, поскольку они делают запрос не SARGable , но самый простой способ сделать это (как предложил Эдгар в комментарии):или
источник