У меня есть список, который я хотел бы, чтобы включить на п where
с помощью or
S:Multiple ИЛИ статьи
my_list = [
%{min: 1, max: 10},
%{min: 4, max: 16},
%{min: 5, max: 21}
]
where
Пунктом Я намерен построить собирается быть частью другого, более крупный запрос.
Прямо сейчас я должен написать следующий код (обратите внимание на дублирование):
query =
my_list
|> Enum.with_index()
|> Enum.reduce(bigger_query, fn {item, index}, q ->
if index == 0 do
where(q, [table], fragment("? BETWEEN ? AND ?", table.age, ^item["min"], ^item["max"]))
else
or_where(q, [table], fragment("? BETWEEN ? AND ?", table.age, ^item["min"], ^item["max"]))
end
end)
Может ли этот запрос быть переписан проще с точки зрения Экто? Если да, то как?
Обновление. Рассмотрим следующий пример:
query = from posts in Post, where: posts.author_id == ^12
query =
my_list
|> Enum.with_index()
|> Enum.reduce(bigger_query, fn {item, index}, q ->
if index == 0 do
where(q, [posts], fragment("? BETWEEN ? AND ?", posts.author_age, ^item["min"], ^item["max"]))
else
or_where(q, [posts], fragment("? BETWEEN ? AND ?", posts.author_age, ^item["min"], ^item["max"]))
end
end)
query = where(q, [posts], posts.published == ^true)
Запрос генерируется правильно:
SELECT * FROM posts WHERE author_id = 12 AND ((age BETWEEN 1 AND 10) OR (age BETWEEN 4 AND 16) AND (age BETWEEN 5 AND 21))
Что бы самый компактный Ecto код для достижения этой цели?
из [docs в 'or_where'] (https://hexdocs.pm/ecto/2.1.3/Ecto.Query.html#or_where/2): * (он) ведет себя точно так же, как и где, кроме объединения с любым предыдущим выражением с использованием OR *. Я вижу это точное поведение: если 'large_query' уже имеет хотя бы одно предложение' where', то запуская 'or_where' будет' OR' в это уже существующее предложение, что нежелательно. Вместо этого мне нужно иметь 'AND (bunch_of_ORs)' – gmile
. Но тогда работает ли более длинный код, который у вас был в вопросе? – Dogbert
'|> где ([p], 1 == 1) |> где ([p], 2 == 2) |> or_where ([p], 3 == 3)' производит этот SQL для меня: 'WHERE ((1 = 1) И (2 = 2)) ИЛИ (3 = 3), т.е. все существующие 'WHERE' объединены и' OR''d против первого 'или_where'. – Dogbert