Question

J'ai cette énorme requête laide ci-dessous, j'aimerais la trier dans une vue catalogue.Penser à quelque chose comme http://wow.dev:3000/catalog_items?&order=deals.Un million de mercis d'avance pour tout commentaire ou réponse.

select 100 - round((current_price / item.estimated_price)*100) as percent, item.cached_thumbnail_url, item.item_id, it.name,
          ci.current_price, ci.close_date
           from item
           join catalog_item ci on ci.item_id = item.item_id
           join item_translations as it on (it.item_id = item.item_id)
           where  (100 - round((current_price / item.estimated_price)*100)) > 49 and 
           item.estimated_price > 0 and ci.current_price > 0 and ci.close_date > now() and item.active = 1 and ci.active = 1 and 
           (current_price / estimated_price) < 1
           order by (ci.close_date < DATE_ADD(now(), INTERVAL 17 hour))  and (item.estimated_price - current_price) desc
           limit 12
Était-ce utile?

La solution

Je ne sais pas comment cela pourrait être lié au ROR, mais quand même :

  1. Tu as 100 - round((current_price / item.estimated_price)*100) as percent dans votre clause SELECT, mais de toute façon en utilisant la même expression dans les conditions WHERE.

  2. Peut item.estimated_price être inférieur à zéro ?Sinon le item.estimated_price > 0 la condition est excessive, si elle est nulle, le (100 - round((current_price / item.estimated_price)*100)) > 49 la condition sera fausse

  3. Le (current_price / estimated_price) < 1 est excessif pour les mêmes raisons

Votre requête peut donc être réécrite un peu plus clairement comme ceci :

select (100 - round((current_price / item.estimated_price)*100)) as percent,
   item.cached_thumbnail_url, item.item_id, it.name,
   ci.current_price, ci.close_date
from item
   join catalog_item ci on ci.item_id = item.item_id
   join item_translations as it on (it.item_id = item.item_id)
where
   percent > 49
   and ci.current_price > 0
   and ci.close_date > now()
   and item.active = 1
   and ci.active = 1
order by
   (ci.close_date < DATE_ADD(now(), INTERVAL 17 hour))
   and (item.estimated_price - current_price) desc
limit 12

Cela n'améliore pas beaucoup la situation, mais je ne peux pas en dire plus sans connaître d'autres raisons concernant votre architecture DB.

BTW, le lien dans votre question ne fonctionne pas (c'est votre lien local évidemment)

Autres conseils

En vous basant sur la réponse du code binaire, vous pouvez essayer d'encapsuler votre requête dans ARel, puis dans l'action de votre contrôleur, vous ordonneriez sur le champ transmis dans le hachage des paramètres, quelque chose comme ceci :

class ItemsController < ApplicationController
  ...
  def index
    @items = Item.select(%{(100 - round((current_price / item.estimated_price)*100)) as percent,
               item.cached_thumbnail_url, item.item_id, it.name,
               ci.current_price, ci.close_date}).
             joins('join catalog_item ci on ci.item_id = item.item_id').
             joins('join item_translations as it on (it.item_id = item.item_id)').
             where('percent > 49 and ci.current_price > 0 and ci.close_date > now() and item.active = 1 and ci.active = 1').
             order(%{(ci.close_date < DATE_ADD(now(), INTERVAL 17 hour))
               and (item.estimated_price - current_price) desc)}).limit(12)
    @items = @items.order(params[:order]) if params[:order]
    ...
end

MODIFIER

Comme le code binaire le souligne ci-dessous, vous souhaiterez peut-être rendre le code du contrôleur plus propre en déplaçant la requête principale en dehors de l'action, probablement dans une méthode du Item modèle, et en vous assurant de toujours retourner un Relation objet à partir de celui-ci (comme le fait l'instruction actuelle), afin que vous puissiez enchaîner l'extra order plus tard:

def index
  @items = Item.by_price_ratio
  @items = @items.order(params[:order]) if params[:order]
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top