Ответы:
Вы можете добавить новое сопоставление в ваш запрос выбора, чтобы найти регистр с учетом или без учета.
-- Case sensitive example
SELECT *
FROM TABLE
WHERE Name collate SQL_Latin1_General_CP1_CS_AS like '%hospitalist%'
-- Case insensitive example
SELECT *
FROM TABLE
WHERE Name collate SQL_Latin1_General_CP1_CI_AS like '%hospitalist%'
Просто помните о проблемах производительности, которые могут возникнуть. Вам нужно будет сканировать кластерный индекс, чтобы настроить / найти значения при выполнении сопоставления. То, как вы пишете LIKE
кусок, также делает запрос несортируемым.
Я подобрал уловку сличения из классов семинара SELECT Кендры Литтл . Вы можете найти дополнительную информацию о сопоставлении от Ben Snaidero из MS SQL Tips.
Хотя вы можете использовать скалярную функцию, такую как UPPER или LOWER, и вы можете повторно сопоставить столбец, чтобы он больше не учитывал регистр, все эти подходы требуют преобразования данных в базовые данные, которые никогда не позволят выполнить поиск по индексу. Вы также ведете свой LIKE с помощью подстановочного знака, так что в любом случае это не так важно для вас в этом сценарии, но если вы когда-нибудь хотели найти эффективный способ поиска левой части строки И включить оптимизатор для поиска по индексу вы можете указать строку в скобках ([]) следующим образом:
SELECT *
FROM TABLE
WHERE Name LIKE '[hH][oO][sS][pP][iI][tT][aA][lL][iI][sS][tT]%'
Этот пример ( ссылка на dbfiddle здесь ) лучше показывает, что я имею в виду:
CREATE TABLE #tmp_cohellation_fun
(
ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, myValue VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CS_AS
)
-- Garbage values to represent data you don't want
INSERT INTO #tmp_cohellation_fun
SELECT CAST(NEWID() AS VARCHAR(50))
FROM master.sys.configurations t1
CROSS JOIN master.sys.configurations t2
CROSS JOIN master.sys.configurations t3;
-- Sprinkle a little bit of good data
INSERT INTO #tmp_cohellation_fun
(myValue)
VALUES ('Apple')
, ('apple')
-- Another healthy helping of garbage that we don't care about
INSERT INTO #tmp_cohellation_fun
SELECT CAST(NEWID() AS VARCHAR(50))
FROM master.sys.configurations t1
CROSS JOIN master.sys.configurations t2
CROSS JOIN master.sys.configurations t3;
-- Some more good data
INSERT INTO #tmp_cohellation_fun
(myValue)
VALUES
('aPple')
, ('APPLE')
, ('APple')
-- Final insert of garbage that we don't care about
INSERT INTO #tmp_cohellation_fun
SELECT CAST(NEWID() AS VARCHAR(50))
FROM master.sys.configurations t1
CROSS JOIN master.sys.configurations t2
CROSS JOIN master.sys.configurations t3
;
-- Create a nonclustered rowstore index
CREATE INDEX ix_myValue ON #tmp_cohellation_fun (myValue)
;
SET STATISTICS XML ON
;
-- Seek, but incorrect results
SELECT *
FROM #tmp_cohellation_fun
WHERE myValue LIKE 'apple%'
;
-- Scan, with correct results
SELECT *
FROM #tmp_cohellation_fun
WHERE myValue COLLATE SQL_Latin1_General_CP1_CI_AS LIKE 'apple%'
;
-- Seek, with correct results
SELECT *
FROM #tmp_cohellation_fun
WHERE myValue LIKE '[aA][pP][pP][lL][eE]%'
;
SET STATISTICS XML OFF
;
DROP TABLE IF EXISTS #tmp_cohellation_fun
И это, и COLLATE
ответ будут влиять на производительность, поскольку они делают запрос не SARGable , но самый простой способ сделать это (как предложил Эдгар в комментарии):
WHERE LOWER(Name) LIKE '%hospitalist%'
или
WHERE UPPER(Name) LIKE '%HOSPITALIST%'
select
время. Вы можете сделать это, создав новый столбец с преобразованным подмножеством данных, а затем индексировать его, как правило, в периоды, когда вы запускаете ETL. Это будет стоить содержание и не очень хороший метод. Б) Вы можете сделать поиск по запросу спорным или раздражительным. Изменение запроса, чтобы бытьSELECT * FROM TABLE WHERE VALUE LIKE %hospitalist
илиSELECT * FROM TABLE WHERE VALUE LIKE hospitalist%
будет работать. Кроме того, вы смотрите на оборудование или функции, чтобы увеличить скорость при плохом дизайне.