Как лучше всего выбирать строковые поля на основе диапазонов символов?

StackOverflow https://stackoverflow.com/questions/152537

Вопрос

Мне нужно добавить пользователям моего программного обеспечения возможность выбирать записи по диапазонам символов.
Как я могу написать запрос, который возвращает все виджеты из таблицы, имя которой попадает, например, в диапазон Ba-Bi?

В настоящее время я использую операторы «больше» и «меньше», поэтому приведенный выше пример будет выглядеть так:

select * from widget
where name >= 'ba' and name < 'bj'

Обратите внимание, как я «увеличил» последний символ верхней границы с i на j, чтобы «велосипед» не остался без внимания.

Существует ли общий способ найти следующий символ после заданного символа на основе сопоставления поля или было бы безопаснее создать второе условие?

select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')

Мое приложение должно поддерживать локализацию.Насколько чувствителен такой запрос к различным наборам символов?

Мне также необходимо поддерживать как MSSQL, так и Oracle.Каковы мои варианты обеспечения игнорирования регистра символов независимо от того, какой язык присутствует в данных?

Это было полезно?

Решение

Перейдем непосредственно к локализации.Вы бы сказали «аа» >= «ба»?Вероятно, нет, но в Швеции это так.Кроме того, вы просто не можете предполагать, что можете игнорировать регистр в любом языке.Регистр явно зависит от языка, наиболее распространенным примером является турецкий:заглавная буква i — это İ.Строчная буква I — ı.

Теперь ваша база данных SQL определяет результат <, == и т. д. с помощью «порядка сопоставления».Это определенно зависит от языка.Таким образом, вы должны явно контролировать это для каждого запроса.Турецкий порядок сортировки поместит эти i на свои места (на турецком языке).Вы не можете полагаться на параметры сортировки по умолчанию.

Что касается «приращения», не беспокойтесь.Придерживайтесь >= и <=.

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

Для MSSQL см. эту тему: http://bytes.com/forum/thread483570.html .

Для Oracle это зависит от вашей версии Oracle, поскольку Oracle 10 теперь поддерживает запросы, подобные регулярным выражениям (p): http://www.psoug.org/reference/regexp.html (найдите regexp_like) и посмотрите эту статью: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html

ХТХ

К сожалению, функция подстроки Oracle — это SUBSTR(), а в SQL-Server — SUBSTRING().

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

Тогда вы можете просто использовать

MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'

или похожие.

Вы могли бы использовать это...

select * from widget
where name Like 'b[a-i]%'

Это будет соответствовать любой строке, где имя начинается с b, второй символ находится в диапазоне от a до i, а за ним следуют любые другие символы.

Я думаю, что я бы выбрал что-нибудь простое, например добавление строки высокой сортировки в конец верхней границы.Что-то вроде:

select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'

Я не уверен, что это выдержит преобразование EBCDIC.

Вы также можете сделать это следующим образом:

select * from widget
where left(name, 2) between 'ba' and 'bi'

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

declare @CriteriaLength int
set @CriteriaLength = 4
select * from widget
where left(name, @CriteriaLength) between 'baaa' and 'bike'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top