2016-06-02 19 views
1

Ich versuche, einen Datensatz zu finden und es am Tag der Schränke basierend auf dem aktuellen Tag zu bestellen.Der nächste Tag in Array sql

Lassen Sie mich versuchen, mit einem Beispiel zu veranschaulichen.

Sagen Sie, dass John herausfinden will, wann er als nächstes unterrichten muss. John unterrichtet die folgenden Tage (Tage werden in Zahlen umgewandelt, wobei 0 = Sonntag, 1 = Montag ...) [1,2]. Der aktuelle Tag ist Freitag (5) und das Ergebnis sollte sein.

Ein weiteres Beispiel:

Karen will, um herauszufinden, wenn sie neben unterrichten hat. Karen lehrt die folgenden Tage [0,2,3]. Der aktuelle Tag ist Donnerstag (4) und das Ergebnis sollte sein.

Aktuelle Abfrage:

TeamOverview.where(coach: current_user.id).order(:day = [next closets day missing here]) 

Modell:

t.string :name 
    t.integer :coach 
    t.int  :day 

Mögliche Datensätze Modell:

id: 1, name: John, day: 1 
id: 2, name: John, day: 2 
id: 3, name: Karen, day: 0 
id: 4, name: Karen, day: 2 
id: 5, name: Karen, day: 3 
+0

wiederholen sich die Tage wie [0,2,4,0,1]? – chaitanya

+0

@chaitanya Nein, Sie können es wie eine Menge behandeln, wo jedes Vorkommen nur einmal erscheint –

Antwort

0

für den nächsten Tag sortiert oben bekommen müssen Sie über Entfernung von heutige Tag.

Leider ist die % (Modulo-Operator mit postgresql hält das Zeichen für negative Werte also nicht day - current_day verwenden können

Aber die Ordnung auf folgenden Ausdruck werden die Zeilen nach Ihren intened Logik sortieren:..

(7 + day - current_day) % 7 

day wo der Tag die Modellreihe bilden und current_day ist der Wert für den aktuellen Tag mit der Berechnung zu verwenden.

Wenn Sie eine explizite Lösung bevorzugen Sie

drehen könnte
CASE WHEN day < current_day THEN 7 + day - current_day ELSE day - current_day END 
+0

Ich bin mir nicht sicher, wie Sie das in die Auftragserklärung integrieren würden? –

1

Um eine komplexe Lösung vermeide ich lieber alle Arbeitstage wählen würde und die Arbeit in Ruby tun. Die maximale Anzahl der Ergebnisse aus der Abfrage ist 7 - das sollte in Ordnung sein. Außerdem sind die Änderungen so hoch, dass Sie bereits eine solche Abfrage haben (möglicherweise auf TeamOverview beschränkt), Sie können diese wiederverwenden und bei einem zweiten Aufruf kann sie auch aus dem Abfrage-Cache kommen.

working_days = TeamOverview.where(coach: current_user.id).pluck(:day) 
working_days.find { |day_num| day_num > today_num } || working_days.first 
-1

folgende Code wird nächsten Tag finden, wenn Sie Tage brauchen, dann entfernen .first Argument

next_day = TeamOverview.where("day > ? and coach_id = ?", current_day, current_user.id).order("day").first 
+0

Das gibt mir einen Fehler: PG :: UndefinedFunction: ERROR: Operator existiert nicht: Zeichenvariable> Ganzzahl –

+0

Das vermisst den Punkt. 'next_day' kann eine niedrigere Zahl als' current_day' sein. Das macht die Frage an erster Stelle problematisch. –

0
(res =TeamOverview.where(coach: current_user.id).order("day").find(:first, :conditions => [ "(day > ?)",current_day])) ? res : TeamOverview.where(coach: current_user.id).order("day").find(:first, :conditions => [ "(day < ?)",current_day]) 

Dies gibt Ihnen gewünschte Ergebnis

+0

Dies ist keine gültige Syntax. Sie könnten * stattdessen etwas tun: 'res = TeamOverview.where (coach: current_user.id) .order (" Tag "). Find (: first,: conditions => [" (tag>?) ", Current_day])) || TeamOverview.where (coach: current_user.id) .order ("Tag"). First', obwohl dies keine ideale Lösung ist, da Sie keine vollständige Bestellung der nächsten Tage zurückgeben; Stattdessen holen Sie nur den * nächsten * Tag. (Was für OPs Bedürfnisse ausreichend sein kann, bin ich nicht sicher.) –

0

Sie können dies in reinen SQL erreichen mit einer zweiteiligen Bestellung:

Eine einfache Implementierung in ActiveRecord hierfür ist:

TeamOverview 
    .where(coach: current_user.id) 
    .order("day < #{current_day}") 
    .order(:day) 

Oder, wenn Sie bevorzugen:

TeamOverview 
    .where(coach: current_user.id) 
    .order("day < #{current_day}, day") 

Warnung: Der obige Code für SQL-Injection potentiell anfällig ist. Stellen Sie sicher, dass Sie der Quelle von current_day vertrauen, und bereinigen Sie (in diesem Fall wahrscheinlich nur to_i anrufen), falls erforderlich.

Leider looking at the rails source code (Stand der aktuellen 4.2.6 Version zum Zeitpunkt der Buchung), es sieht aus, als ob die ? Syntax nicht von der order Active Methode unterstützt wird - das heißt, die folgende ungültig ist: TeamOverview.order("day < ?", current_day). Vielleicht wäre das eine gute Ergänzung für die Bibliothek.

Verwandte Themen