Sortieren nach SQL-Abfrage mithilfe eines URL-Parameters
-
11-12-2019 - |
Frage
Ich habe unten diese riesige, hässliche Abfrage, ich möchte sie in einer Katalogansicht sortieren.Ich denke so etwas wie http://wow.dev:3000/catalog_items?&order=deals.Vielen Dank im Voraus für alle Kommentare oder Antworten.
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
Lösung
Ich bin mir nicht sicher, wie das mit ROR zusammenhängen könnte, aber trotzdem:
Du hast
100 - round((current_price / item.estimated_price)*100) as percent
in Ihrer SELECT-Klausel verwenden, aber trotzdem denselben Ausdruck in WHERE-Bedingungen verwenden.Kann
item.estimated_price
kleiner als Null sein?Wenn nichtitem.estimated_price > 0
Der Zustand ist übertrieben, wenn er Null ist(100 - round((current_price / item.estimated_price)*100)) > 49
Bedingung wird falsch seinDer
(current_price / estimated_price) < 1
ist aus den gleichen Gründen übertrieben
Ihre Abfrage kann also etwas klarer wie folgt umgeschrieben werden:
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
Dies verbessert die Situation nicht wesentlich, aber ich kann nicht mehr sagen, ohne weitere Gründe für Ihre DB-Architektur zu kennen.
Übrigens funktioniert der Link in Ihrer Frage nicht (es ist offensichtlich Ihr lokaler Link).
Andere Tipps
Aufbauend auf der Antwort von Binarycode können Sie versuchen, Ihre Abfrage in ARel zu verpacken, und dann in Ihrer Controller-Aktion eine Bestellung für das Feld aufgeben, das im Parameter-Hash übergeben wurde, etwa so:
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
BEARBEITEN
Wie der Binärcode weiter unten zeigt, möchten Sie möglicherweise den Controller-Code sauberer gestalten, indem Sie die Hauptabfrage außerhalb der Aktion verschieben, wahrscheinlich in eine Methode in der Item
Modell, und stellen Sie sicher, dass Sie trotzdem ein zurücksenden Relation
Objekt daraus (wie es die aktuelle Anweisung tut), sodass Sie das Extra verketten können order
später:
def index
@items = Item.by_price_ratio
@items = @items.order(params[:order]) if params[:order]
end