Расширенное использование выражения «как» в sqlite - PullRequest
0 голосов
/ 20 марта 2011

Сейчас я работаю над sqlite на платформе iPhone и работаю с базой данных с некоторыми странными объектами.Один из столбцов в этой БД называется типом, который допускает несколько значений (несколько типов).Данные в этом столбце выглядят следующим образом:

1|9|20|31|999

Таблица выглядит следующим образом:

ID       TYPE
------------------------
1        1|9|20|31|999
2        5|13|15|30|990
3        6|7|45|46|57

Когда пользователь хочет выбрать данные с типом 9, он должен выбрать вышеданные, потому что объект содержит 9. И я использую следующий оператор для выполнения:

SELECT id
  FROM table 
 WHERE type LIKE '%' || ? || '%'

Проблема в том, что данные с типом 999 и без типа 9 также будут выбраны.Кроме того, если пользователь хочет выбрать тип 1, также будут выбраны данные с типом 11, 12, 13 и т. Д.

Я попытался использовать выражение:

SELECT id
  FROM table 
 WHERE type LIKE '[^0123456789]' || ? || '[^0123456789]'

Но он не может выбрать какие-либо данные.

Что я могу сделать, чтобы выбрать данные с правильным типом?

(База данных не может быть изменена из-за требований компании)

Ответы [ 3 ]

2 голосов
/ 20 марта 2011

Вам понадобится регулярное выражение, которое соответствует только 'yournumber|', '|yournumber|', '|yournumber' или их комбинации. Я не вижу способа, чтобы оптимизатор мог использовать индекс для такого рода вещей, кроме специализированного индекса, который работал бы так же, как полнотекстовые индексы.

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

Если объем данных невелик, попробуйте просто выбрать like '%number%' и выполнить некоторую постобработку кода своего приложения.

В противном случае нормализуйте ваши данные.

0 голосов
/ 20 марта 2011

Вы можете попробовать это

SELECT id
  FROM table 
 WHERE '|' + type + '|' LIKE '%|' + ? + '|%'

(здесь я использую оператор +, потому что его легче читать, но вместо этого можно использовать ||)

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

У меня был похожий вопрос Я задавал себе вопрос некоторое время назад.Также проверьте это ответ

0 голосов
/ 20 марта 2011

Я не слишком знаком с SQLite, но как насчет:

SELECT id FROM table WHERE type REGEX '(^9\|.*)|(.*\|9\|.*)|(.*\|9$)';

при условии, что вы ищете тип 9

Затем искать тип 999это будет:

SELECT id FROM table WHERE type REGEX '(^999\|.*)|(.*\|999\|.*)|(.*\|999$)';

Обратите внимание, что вы можете настроить выражение, если у вас может быть значение типа в поле type, потому что в этом случае я бы предположил, что не будетбыть любым | символом.

...