Отдельное предложение игнорируется, если вызывается предложение группы

#ruby-on-rails #ruby #postgresql #activerecord

Вопрос:

Для LineItem модели я получаю сумму количества заказа для каждой позиции. В этом примере я выбираю только одну позицию для краткости.

Запрос:

 LineItem
  .where(product_id: 14)
  .includes(:order, :product)
  .where(orders: { order_type: 1, order_date: (Date.today - 1.week)..Time.now})
  .sum(:order_quantity)
 

Это порождает

 => 88
 

что неточно. выщипывание идентификатора элемента строки показывает мне, что некоторые элементы строки запрашиваются более одного раза:

 LineItem
  .where(product_id: 14)
  .includes(:order, :product)
  .where(orders: { order_type: 1, order_date: (Date.today - 1.week)..Time.now})
  .pluck(:id)
 

Много дубликатов (до сих пор не понял, почему это происходит в первую очередь):

 => [20330, 20330, 20358, 20358, 20361, 20361, 20363, 20363, 20369, 20405, 20405, 20452, 20452, 20513, 20513, 20513, 20527]
 

Хорошо, давайте назовем их четко…

 LineItem
  .distinct
  .where(product_id: 14)
  .includes(:order, :product)
  .where(orders: { order_type: 1, order_date: (Date.today - 1.week)..Time.now})
  .sum(:order_quantity)
 

Это порождает

 => 27
 

что совершенно верно. Поскольку я также пытаюсь объединить несколько строк в хэш, мне нужно вызвать предложение group в конце запроса; именно здесь начинается проблема:

 LineItem
  .distinct
  .where(product_id: 14)
  .includes(:order, :product)
  .where(orders: { order_type: 1, order_date: (Date.today - 1.week)..Time.now})
  .group('products.model_number')
  .sum(:order_quantity)
 

теперь, даже .distinct будучи вызванным, он вернулся к извлечению повторяющихся позиций:

 => {"LBP8652"=>88}
 

Я упускаю здесь что-то очевидное? Я попытался добавить это .distinct в другое место запроса, но
это все равно дает те же неточные результаты.

Комментарии:

1. «все еще не понял, почему это происходит в первую очередь» Это ваша реальная проблема, и у нас недостаточно подробной информации о ваших данных или ваших отношениях, чтобы помочь здесь. Вы, конечно, могли бы создать более сложные запросы, чтобы обойти эту проблему, однако это было бы намного сложнее, чтобы избежать устранения причины проблемы.

2. .includes(:order, :product) это очень неправильно. .includes используется для предотвращения проблем с запросами n 1, и эвристика создаваемых им запросов довольно сложна. Ты хочешь .joins или .left_joins .