Каков наилучший способ выбора строковых полей на основе диапазонов символов? - PullRequest
5 голосов
/ 30 сентября 2008

Мне нужно добавить возможность пользователям моего программного обеспечения выбирать записи по диапазонам символов.
Как я могу написать запрос, который возвращает все виджеты из таблицы, чье имя находится в диапазоне 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. Каковы мои варианты обеспечения того, чтобы регистр символов игнорировался независимо от того, какой язык отображается в данных?

Ответы [ 6 ]

3 голосов
/ 30 сентября 2008

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

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

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

0 голосов
/ 30 сентября 2008

Вы также можете сделать это так:

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'
0 голосов
/ 30 сентября 2008

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

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

Я не уверен, что переживет преобразование EBCDIC, хотя

0 голосов
/ 30 сентября 2008

Вы можете использовать это ...

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

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

0 голосов
/ 30 сентября 2008

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

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

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

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

или аналогичный.

0 голосов
/ 30 сентября 2008

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

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

НТН

...