Используя ROM-SQL или Sequel, как я могу запросить несколько записей, используя несколько столбцов (с разными значениями в каждой строке)?
Учитывая таблицу базы данных с этими тремя строками:
Примечание. Я специально опустил здесь, потому что мы можем иметь дело со случаем, когда либо у нас нетid
или, может быть[first_name, last_name]
является составным первичным ключом.
Как мне получить Джона Доу и Уилла Смита без одновременного получения Джона Смита за одно обращение к базе данных?
Мы можем сделать это для одной записи:
- Мы можем использовать
rom-sql
by_pk
метод для извлечения одной записи по составным первичным ключам (если это составной первичный ключ).
users.by_pk('John', 'Doe')
- Мы можем использовать
where
(практически из любого адаптера базы данных), чтобы получить запись
users.where(first_name: 'John', last_name: 'Doe')`
Но как сделать то же самое для нескольких записей?
(1) не работает (по крайней мере, я не знаю синтаксиса). Пожалуйста, просветите меня, если вы делаете!
Тривиальный способ — просто запустить карту в Ruby и получить ее:
array_of_first_names_and_last_names.map do |first_name_and_last_name|
first_name, last_name = first_name_and_last_name
users.by_pk(first_name, last_name)
end
Мы можем сделать ту же тривиальную карту в Ruby для (2).
Но как мы можем сделать это за одну базу данных?
(2) не работает, потому что я также случайно получу Джона Смита, если просто сделаю это:
users.where(first_name: ['John', 'Will'], last_name: ['Doe', 'Smith'])
Опишите, что вы пробовали
Я пытался сделать это в Sequel (и вы можете сделать это и в SQL, если хотите):
def find_all_by_pk(array_of_first_names_and_last_names:) # [['John', 'Doe'], ['Will', 'Smith']]
dataset = users.dataset
array_of_first_names_and_last_names.each.with_index do |first_name_and_last_name, index|
first_name, last_name = first_name_and_last_name
index += 1
dataset = if index == 1
dataset.where(first_name: first_name, last_name: last_name)
else
dataset.or(first_name: first_name, last_name: last_name)
end
end
dataset.to_a
end
ОБНОВЛЕНИЕ: несколько месяцев спустя (17 ноября 2022 г.) я наткнулся на свой вопрос, пытаясь решить аналогичную проблему. Все, что мне удалось сделать, это сделать часть Ruby немного чище:
def find_all_by_pk(array_of_first_names_and_last_names:) # [['John', 'Doe'], ['Will', 'Smith']]
head, *tail = array_of_first_names_and_last_names
initial_query = users.dataset.where(first_name: head[0], last_name: head[1])
tail.reduce(initial_query) do |query, first_name_and_last_name|
first_name, last_name = first_name_and_last_name
query.or(first_name: first_name, last_name: last_name)
end.to_a
end
Есть ли лучший/более чистый/более идиоматический способ сделать это?