Регулярное выражение Rails SQL
Я пытаюсь найти максимальное число в сериях A0001, A0002, A1234, A2351 и т.д. Проблема в том, что в списке, который я ищу, также есть строки, такие как AG108939, E092357, AL399, 22-30597 и т.д.
Итак, в основном, я хочу получить значение A #### в моей базе данных. Я использовал следующий запрос:
@max_draw = Drawing.where("drawing_number LIKE ?", "A%")
Что работало до тех пор, пока такие числа, как AG309, не начали мешать, потому что он начинается с A, но имеет другой формат, чем тот, который я ищу.
Я предполагаю, что это должно быть довольно просто с регулярными выражениями, но я новичок в этом и не знаю, как правильно писать этот запрос с регулярным выражением. Вот некоторые вещи, которые я пробовал, которые просто возвращают нуль:
@max_draw = Drawing.where("drawing_number LIKE ?", /A\d+/)
@max_draw = Drawing.where("drawing_number LIKE ?", "/A\d+/")
@max_draw = Drawing.where("drawing_number LIKE ?", "A[0-9]%")
Ответы
Ответ 1
Ты проделал хорошую работу! Недостатком была функция REGEXP
, которая используется для регулярных выражений в запросах:
Итак, в вашем случае используйте
Drawing.where("drawing_number REGEXP ?", 'A\d{4}')
# the {4} defines that there have to be exactly 4 numbers, change if you need to
В SQL вы используете '-colons
, что странно, потому что вы обычно запускаете регулярное выражение с помощью /-backslashes
Ответ 2
В Rails 4+ с базой данных Postgres общий вид запроса RegEx:
Model.where("column ~* ?", 'regex')
Что касается регулярного выражения, он может быть общим '^A\d+$'
или более конкретным '^A\d{4}$'
Разрушение:
^ - string start anchor
A - literal "A"
\d+ - one or more digits (0-9)
\d{4} - exactly four digits
$ - string end anchor
В основном, регулярное выражение читает "строка должна начинаться с буквы A, а затем четырех цифр, а затем строка должна заканчиваться".
Конечная строка запроса:
@max_draw = Drawing.where("drawing_number ~* ?", '^A\d{4}$')
Дальнейшее чтение на Ruby RegEx на RubyDoc или более доступный Perl вариант (используется Sublime text)
Ответ 3
Вы не можете использовать регулярные выражения в SQL, которые вы пытаетесь сделать. Лучше всего выбрать только те записи, которые начинаются с A, как ваш исходный код, а затем пропустить записи, которые содержат более одной буквы в начале.
items = Drawing.where( [ 'drawing_number LIKE ?' , 'A%' ] )
max_value = 0
items.each do |item|
next if item.drawing_number =~ /\A[A-Za-z]{2,}/
drawing_number = item.drawing_number.gsub(/\AA/, '').to_i
max_value = drawing_number if drawing_number > max_value
end
Я уверен, что это возможно сделать короче, но это должно делать то, что вам нужно.
(\ A - начало привязки строки, которое работает со строками, содержащими символы новой строки)
({2,} соответствует двум или большему диапазону исходящих символов)
http://www.rubular.com/ является удивительным для тестирования рубиновых регулярных выражений.