Ordina per query SQL utilizzando un parametro URL
-
11-12-2019 - |
Domanda
Di seguito ho questa brutta query enorme, vorrei ordinarla in una visualizzazione del catalogo.Pensare qualcosa del genere http://wow.dev:3000/catalog_items?&order=deals.Un milione di grazie in anticipo per eventuali commenti o risposte.
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
Soluzione
Non sono sicuro di come ciò possa essere correlato al ROR, ma comunque:
Hai
100 - round((current_price / item.estimated_price)*100) as percent
nella clausola SELECT, ma comunque utilizzando la stessa espressione nelle condizioni WHERE.Potere
item.estimated_price
essere inferiore a zero?Se non ilitem.estimated_price > 0
la condizione è eccessiva, se è zero il(100 - round((current_price / item.estimated_price)*100)) > 49
la condizione sarà falsaIL
(current_price / estimated_price) < 1
è eccessivo per gli stessi motivi
Quindi la tua query può essere riscritta un po' più chiaramente in questo modo:
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
Ciò non migliora molto la situazione, ma non posso dire di più senza conoscere ulteriori ragioni sull'architettura del tuo DB.
A proposito, il collegamento nella tua domanda non funziona (ovviamente è il tuo collegamento locale)
Altri suggerimenti
Costruire sulla risposta del BinaryCode, puoi provare a avvolgere la tua query in Arel, quindi nell'azione del controller che si ordina sul campo passò nel parametro hash, qualcosa del genere:
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
.
Modifica
Poiché BinaryCode sottolinea di seguito, è possibile effettuare il detergente del codice del controllore spostando la query principale al di fuori dell'azione, probabilmente in un metodo nel modello Item
e assicurandosi di restituire ancora un oggetto Relation
(come ilDichiarazione attuale), in modo da poter catenere il order
extra in seguito:
.def index
@items = Item.by_price_ratio
@items = @items.order(params[:order]) if params[:order]
end