2016-03-28 15 views
3

Ich habe diese SQL-Abfrage gerade jetzt;5 Datenbankeinträge basierend auf dem Datum anzeigen

SELECT * FROM `articles` WHERE 
`type` = 'press' AND (`published` = '1' AND `time_start` >= '".$time_today."') 
ORDER BY `time_start` ASC, `id` DESC LIMIT 5 

Die Idee ist, dass 5 Artikel immer angezeigt werden. time_start ist die Startzeit, time_end ist die Endzeit (nur PHP's mktime).

Die Artikel sind grundsätzlich Kalendereinträge, es sollten nur Einträge angezeigt werden, die morgen beginnen und nur die ersten fünf. Momentan gibt es weniger als fünf anstehende Kalenderpunkte.

Wie mache ich es im Grunde tun diese Abfrage if num_rows > 5, else fill up with older ones? Sollte ich ein PHP-Fallback betrachten, einfach die Daten mit einer anderen Abfrage überschreiben (die 5 'neuesten' Artikel anzeigen) oder gibt es eine Möglichkeit, dies in der Abfrage selbst zu bearbeiten?

Frage ist nicht so viel darüber, wie es wie die Suche nach der richtigen Art und Weise getan werden könnte, es zu tun, hofft, tut das nicht gegen die Regeln

+0

verwenden Sie diese ORDER BY 'time_start' DESC,' id' DESC LIMIT 0,5 –

Antwort

1

Es sieht also so aus, als ob du ab der Startzeit ein Fenster mit 5 Events haben möchtest .. damit frühere Ereignisse in dem Fall angezeigt werden, in dem weniger bevorstehen.

zwei praktikable Möglichkeiten hier ..

Wenn Sie zufrieden sind mit diesem in der Anwendungslogik zu tun:

Run:

SELECT * 
    FROM articles 
    WHERE type = press 
    AND published = '1' 
    AND time_start >= :time_today 
ORDER BY time_start ASC, id ASC /* 'I thought id should be ascending here */ 
    LIMIT 5 

berechnen, wie viele zusätzliche Artikel, die Sie noch brauchen, und dann:

SELECT * 
    FROM articles 
    WHERE type = press 
    AND published = '1' 
    AND time_start < :time_today 
ORDER BY time_start DESC, id DESC 
    LIMIT :slack 

Einfach die erste Ergebnismenge umkehren und die zweite anhängen und weitergehen.

Wenn Sie dies alles in der DB tun wollen würde ich wahrscheinlich tun:

SELECT * 
    FROM ((
     SELECT * 
     FROM articles 
     WHERE type = press 
     AND published = '1' 
     AND time_start >= :time_today 
    ORDER BY time_start ASC, id ASC 
     LIMIT 5 
      ) 
    UNION ALL 
      (
     SELECT * 
     FROM articles 
     WHERE type = press 
     AND published = '1' 
     AND time_start < :time_today 
    ORDER BY time_start DESC, id DESC 
     LIMIT 5 
     )) window_extents 
ORDER BY time_start DESC, id DESC 
    LIMIT 5 

Dies funktioniert, indem alle möglichen Datensätze für das Fenster auswählen und dann die Ergebnisse Eingrenzung. Es sollte auch Ihre Indizes gut nutzen.

N.B. Es sieht so aus, als ob du das Datum in die Abfrage einfügst, anstatt es zu binden. Ich würde es mir aus Gewohnheit erlauben, dies auch in einer sicheren Umgebung zu tun, wenn es nicht absolut notwendig ist.

0

Einfach Auftrag von der TIME_START und dann eine Grenze von 5 So werden Sie definitiv 5 von der Reihe und entsprechend der Zeit in der Zeit erhalten, die größer ist, als Sie in der Bedingung angeben.

(Vorausgesetzt, Sie haben 5 Einträge für jede Zeit nach der vorgesehenen Zeit)

+0

Das Problem hier ist, dass es die erste von 'jetzt' und die 4, die danach kommen, zeigen muss. Die Idee ist, dass es etwa 40-50 verschiedene Artikel geben wird, die in der Übersicht erscheinen werden, aber diese sind nicht relevant für die hervorgehobenen auf der Startseite ... – Ieuan

0
SELECT date1, 
    IF((unix_timestamp(date1) - unix_timestamp()) > 0, 1, 0) as a, 
    IF((unix_timestamp(date1) - unix_timestamp()) > 0, (unix_timestamp(date1) - unix_timestamp())/10000000, unix_timestamp(date1) - unix_timestamp()) as b 
FROM `test1` WHERE 1 order by a desc, b desc limit 0,5 

Sie mit der PHP alternativen Abfrage gehen sollte, aber wenn Sie möchten, können Sie so etwas wie dieses verwenden. TS sprechend, wenn das Datum in der Zukunft ist, teilen wir es durch eine große Zahl, um es in der Nähe von 0 zu halten, so dass wir sie in der Vergangenheit von TS vergleichen/priorisieren können. Es ist hässlich, ich weiß, p, aber hässlich macht Spaß. Du musst testweise hinzufügen und unix_timestamp() durch $ my_now_timestamp ersetzen und einige Performance-Bedingungen hinzufügen, um zu vermeiden, dass alle Tabellen analysiert werden ...

0

Entfernen Sie einfach den TIME_START Zustand von where-Klausel (AND TIME_START >= '".$time_today."') und Sie haben wenig Ihre Bestellung per Teil etwas wie die unten Abfrage

SELECT * 
FROM `articles` 
WHERE `type` = 'press' 
    AND `published` = '1' 
ORDER BY 
    CASE WHEN `time_start` >= '".$time_today."' 
     THEN 0 ELSE 1 END ASC, 
    CASE WHEN `time_start` >= '".$time_today."' 
     THEN `time_start` END ASC, 
    CASE WHEN `time_start` < '".$time_today."' 
     THEN `time_start` END DESC LIMIT 5 

ändern, wenn es keine 5 Einträge nach dem angegebenen Datum, Sie müssen den vorherigen Datensatz abrufen, um die Zahl 5 zu erhalten. Also müssen Sie die Datumsprüfung entfernen.

Oder Sie können auch diese Unter Abfrage versuchen,

SELECT * 
FROM ( 
    SELECT *,(CASE WHEN `time_start` >= '".$time_today."' 
       THEN 0 ELSE 1 END) oflag 
    FROM `articles` 
    WHERE `type` = 'press' 
     AND `published` = '1' 
) T 
ORDER BY 
     oflag ASC, 
     CASE WHEN oflag = 0 THEN `time_start` END ASC, 
     CASE WHEN oflag = 1 THEN `time_start` END DESC LIMIT 5 
0

Ihre Anfrage sollte:

SELECT * FROM `articles` 
WHERE `type` = 'press' AND `published` = '1' 
AND `time_start` <= DATEADD(NOW(), INTERVAL 1 DAY) 
ORDER BY `time_start` DESC LIMIT 5 

Sie werden fünf Ergebnisse in absteigender Reihenfolge von time_start Feld bekommen. Dies ist die beste Lösung, da Sie immer die 5 neuesten Artikel, die 24 Stunden von NOW() starten, aus der Datenbank holen müssen. Selbst wenn in der Datenbank keine Datensätze mit den Terminen von morgen für type=press gefunden werden, dann werden 5 ältere in absteigender Reihenfolge das Ergebnis der Abfrage sein, was Sie auch möchten.

Verwandte Themen