Поиск без учета регистра без использования функции в предложении where

Есть ли способ сделать регистр нечувствительным без использования функции в предложении where?
Пожалуйста, укажите базу данных, о которой вы говорите, когда / если вы ответите. Я знаю, что MySQL уже по умолчанию нечувствителен к регистру. А как насчет Oracle, MSSQL или HANA?

select * from mytable WHERE upper(fieldname) = 'VALUE'

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

Tim Biegeleisen 15.08.2018 07:32

Что ж, для каждого rdbms это отличается - использование строки collate в ответе Wanderer предназначено для SQL Server, использование SET NLS_COMP - для Oracle, а для Sap Hana это может быть совершенно другое.

Zohar Peled 15.08.2018 07:57

upper(columnname) = 'VALUE' будет работать практически с любыми СУБД. Однако не следует ожидать постоянного использования индекса, поэтому производительность может быть очень низкой.

jarlh 15.08.2018 10:03

Я думаю, что вопрос о 4 базах данных слишком широк.

Gordon Linoff 15.08.2018 13:38

Согласитесь с @GordonLinoff, что вопрос кажется слишком широким, чтобы дать один лучший ответ. Кроме того, важной мотивацией этого вопроса, по-видимому, является то, что решения по-прежнему должны разрешать использование индексов в СУБД. Тогда это должно быть частью вопроса.

Lars Br. 15.08.2018 22:45
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
5
2 067
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

collate SQL_Latin1_General_CP1_CS_AS.

Сопоставление по умолчанию - SQL_Latin1_General_CP1_CI_AS, то есть case insensitive. И если нам нужно сделать его чувствительным к регистру, то добавление COLLATE Latin1_General_CS_AS делает поиск чувствительным к регистру.

Запрос

select * from [mytable] 
where [fieldname] = 'VALUE' collate SQL_Latin1_General_CP1_CS_AS;

Find a demo here

Это для MS SQL Server, Hana или Oracle?

jarlh 15.08.2018 10:00

@jarlh: MS SQL Server

Ullas 15.08.2018 10:03

Я ищу, как это сделать в mssql, oracle и hana. Я хочу понять как.

Steve Lloyd 15.08.2018 17:04

Поскольку ваш вопрос помечен как Oracle, я предоставлю решение, которое работает в Oracle.

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

SQL> alter session set NLS_COMP=ANSI;
SQL> alter session set NLS_SORT=BINARY_CI; 
SQL> select 1 from DUAL where 'abc' = 'ABC';

         1
----------
         1

Подробнее на Лингвистическая сортировка и поиск по строкам

как отмечает @mathguy,

ALTER SESSION SET NLS_COMP=LINGUISTIC; 

встречается чаще, чем использование ANSI

Я бы добавил: _CI означает "нечувствительность к регистру"; NLS_COMP также должен быть (пере) установлен, по умолчанию - BINARY, и его следует сбросить на LINGUISTIC (ANSI тоже работает, но LINGUISTIC более распространен). Кроме того, с точки зрения стиля, вероятно, лучше заключить значения в одинарные кавычки, хотя Oracle позволяет BINARY_CI и тому подобное появляться без кавычек.

mathguy 15.08.2018 07:50

Использование верхнего (или нижнего) регистра столбца для сравнения - это стандартный способ сравнения без учета регистра. (UPPER и LOWER - это функции, определенные в стандарте SQL.)

Если вы не хотите применять функцию к столбцу, вы, конечно, можете написать рекурсивный запрос для генерации всех перестановок верхнего / нижнего регистра значения ('VALUE', 'VALUE', 'VaLUE', ... , 'значение') и проверьте, находится ли значение вашего столбца в этом наборе. Стандартный SQL предоставляет функцию SUBSTRING для доступа к подстрокам (например, n-й букве) и CHAR_LENGTH для получения длины строки.

Степень поддержки стандарта зависит от используемой СУБД и ее версии. В Oracle, например, это SUBSTR вместо SUBSTRING и LENGTH вместо CHAR_LENGTH. MySQL, с другой стороны, напрямую поддерживает как SUBSTRING, так и CHAR_LENGTH, но поддерживает только рекурсивные запросы начиная с версии 8.0.

это будет работать:

SELECT *
FROM mytable
WHERE REGEXP_LIKE (column_name, 'value', 'i');

проблема с этим запросом в том, что теперь у вас есть regexp_like в качестве функции в предложении where. Если вы запрашиваете огромную таблицу, эта функция должна выполняться для каждой строки. Моя цель - избавиться от функций в предложении where.

Steve Lloyd 15.08.2018 17:02

но почему вы хотите избавиться от функции в предложении where. вызовет ли это какие-либо проблемы, если это будет большая таблица.

nikhil sugandh 15.08.2018 17:31

использование функций в предложении where обычно не является хорошей идеей, поскольку оно делает индекс недействительным. (если вы также не проиндексировали функцию).

Steve Lloyd 15.08.2018 17:35

Даже если вы избегаете предложения WHERE, изменение логики сравнения часто делает невозможным доступ к индексу. Например. в Oracle для изменения настроек NLS потребуются дополнительные индексы, созданные с этими настройками. См., Например, richardfoote.wordpress.com/2008/01/03/…

Lars Br. 16.08.2018 04:47
Ответ принят как подходящий

Oracle 12c ответ

select * from mytable WHERE fieldname='Value' collate binary_ci

SAP HANA, похоже, не имеет другого выхода, кроме использования верхнего или нижнего.

SQL Server и MySQL не различают прописные и строчные буквы - по умолчанию они нечувствительны к регистру.

Другие вопросы по теме