Используя ROM-SQL или Sequel, как я могу запросить несколько записей, используя несколько столбцов (с разными значениями в каждой строке)?

Учитывая таблицу базы данных с этими тремя строками:

Примечание. Я специально опустил здесь, потому что мы можем иметь дело со случаем, когда либо у нас нетidили, может быть[first_name, last_name]является составным первичным ключом.

Как мне получить Джона Доу и Уилла Смита без одновременного получения Джона Смита за одно обращение к базе данных?

Мы можем сделать это для одной записи:

  1. Мы можем использоватьrom-sql by_pkметод для извлечения одной записи по составным первичным ключам (если это составной первичный ключ).
      users.by_pk('John', 'Doe')
  1. Мы можем использовать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

Есть ли лучший/более чистый/более идиоматический способ сделать это?

0 ответов

Другие вопросы по тегам