2009-07-15 4 views
0

Ich bin mir nicht sicher, ob ich etwas wirklich offensichtlich fehlen, aber ich bekomme immer einen Syntaxfehler bei dieser Abfrage. Selbst wenn ich etwas Offensichtliches verpasse, würde ich gerne wissen, ob es eine klügere Art gibt, das zu bekommen, wonach ich suche.MySQL bedingte Abfrage innerhalb WHERE-Klausel

Grundsätzlich fragt die Abfrage nach Zeilen, die mit einem Benutzer mit einem Startdatum zwischen Montag und Freitag verbunden sind. Das funktioniert großartig. Aber dann habe ich eine bedingte Abfrage hinzugefügt, falls irgendwelche Zeilen für diesen Samstag oder Sonntag vorhanden sind. Beachten Sie, dass die bedingte Abfrage mit einem Samstag oder Sonntag für alle Benutzer überprüft, nicht den Benutzer in der Hauptabfrage:

SELECT user_id, 
DATE_FORMAT(DATE(shift_start),'%m/%d/%Y') date, 
TIME_FORMAT(TIME(shift_start), '%h:%i %p') start, 
TIME_FORMAT(TIME(shift_end), '%h:%i %p') end, 
title 
FROM shifts 
WHERE user_id = '$user_id' 
AND DATE(shift_start) BETWEEN 
DATE_SUB(DATE(NOW()), INTERVAL WEEKDAY(NOW()) DAY) AND 
DATE_ADD(DATE(NOW()), INTERVAL 
    (SELECT 
    IF( 
    COUNT(*) FROM shifts 
    WHERE DATE(shift_start) BETWEEN 
    DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND 
    DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY), 
6, 4)) - WEEKDAY(NOW()) DAY) 
ORDER BY shift_start 

Ich bin eigentlich ziemlich stolz darauf, wie es funktioniert, bevor es mit dem IF-Teil vermasselt, aber wieder, wenn es einen offensichtlich besseren Weg gibt, dies zu tun, bin ich ganz Ohr.

Oh, und wenn dies ausgebügelt wird, wird "Now()" durch eine Datumsvariable ersetzt, die im php-Skript eingerichtet ist (über GET übergeben).


Ehrfürchtige Arbeit, benlumey. Hier ist, was funktioniert:

SELECT user_id, 
     DATE_FORMAT(DATE(shift_start),'%m/%d/%Y') AS shift_start_date, 
     TIME_FORMAT(TIME(shift_start), '%h:%i %p') AS shift_start_time, 
     TIME_FORMAT(TIME(shift_end), '%h:%i %p') AS shift_end_time, 
     title 
FROM shifts 
WHERE user_id = '$user_id' AND 
DATE(shift_start) BETWEEN 
    DATE_SUB(DATE(NOW()), INTERVAL WEEKDAY(NOW()) DAY) 
    AND 
    DATE_ADD 
    (
     DATE(NOW()), INTERVAL 
     (
     SELECT IF(COUNT(*),6,4) 
     FROM shifts 
     WHERE DATE(shift_start) BETWEEN 
      DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) 
      AND 
      DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY) 
     ) - WEEKDAY(NOW()) DAY 
    ) 
+0

Nachdem ich die Abfrage ein paar Mal durchgelesen habe, muss ich zugeben, dass Sie vielleicht ein wenig unnötige Datumsmathematik machen, die MySQL für Sie tun kann, obwohl es vielleicht mein Unverständnis ist. Könnten Sie vielleicht "DATE ​​(shift_start) ZWISCHEN DATE_SUB (DATUM (JETZT()), INTERVALL WOCHENTAG (JETZT()) TAG) UND ..." bis "WOCHENTAG (shift_start) ZWISCHEN 1 UND ..." vereinfachen? – ruquay

+0

Wenn ich nur WEEKDAY (shift_start) zwischen 0 und 4 benutze, werden nicht ALLE Schichten zurückgegeben, die zwischen ANY Montag und Freitag fallen (was fast alle sind)? Vielleicht verpasse ich etwas in deinem Rat. Ich schätze das Feedback jedoch. Es ist ziemlich haarig und scheint etwas zu sein, was MySQL ohne meine lange Version machen kann. – Anthony

Antwort

2

Versuchen Sie, diese Unterabfrage:

(SELECT 
    IF(COUNT(*) > 0, 6, 4)) - WEEKDAY(NOW()) DAY) 
    FROM shifts 
    WHERE DATE(shift_start) BETWEEN 
    DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND 
    DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY) 

Zwei Dinge, die ich habe

getan
  • machte es aussehen wie eine normale Abfrage, die von und wo nicht gehen innerhalb der wenn soweit ich weiß.
  • Setzen Sie eine Bedingung in das if, glaube nicht, dass mysql automatisch 0 als falsch und> 0 als wahr annimmt.
+0

Wenn das von und wo nicht ins if() gehen kann, wäre das wirklich enttäuschend, würde aber alles erklären! Was Ihren zweiten Punkt betrifft, ist 0 genau das was die [if-Anweisung] [1] tut, deshalb wollte ich es verwenden. [1]: [http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if] – Anthony

+0

Außerdem bin ich wirklich im Dunkeln darüber, wie Ihre Unterabfrage das gewünschte erzeugen würde Ergebnis.Was zählt die Zählung und was ist das Iffing? Tut mir leid, seltsam zu klingen. Grundsätzlich meine ich, die if-Funktion scheint so von der Unterabfrage isoliert zu sein, dass ich nicht sehe, wie sie von der Abfrage selbst ausgelöst wird. Auch hier bin ich hier um zu lernen. – Anthony

+0

Und Sie gewinnen den großen Preis! Ich poste, wie ich es getan habe (die wirklich einfache Lösung basierend auf Ihrer Antwort) als Kommentar. – Anthony

1

das auseinander fällt hier:

(SELECT 
    IF( 
     COUNT(*) FROM shifts 
    WHERE DATE(shift_start) BETWEEN 

Die Aussage Zahl wird nicht funktionieren.

Was möchten Sie tun? Sie brauchen eine klare Aussage darüber, was Sie hier erreichen wollen.

Das ist mein Swag es:

(SELECT 
    IF( 
     (select COUNT(*) FROM shifts 
     WHERE DATE(shift_start) BETWEEN 
     DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND 
     DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY))>0,6,4) 
) - WEEKDAY(NOW()) DAY 

Aber ohne zu wissen, was Sie, ich bin nicht sicher, zu tun versuchen.

+0

"SELECT IF (COUNT (*) FROM shifts" sieht nicht richtig aus) –

+0

Ein Select, wenn Select mir in den Sinn kam, schien aber wirklich funky zu sein, ganz zu schweigen davon, dass es einen ernsthaften Engpass verursachen würde Ich komme hierher, um zu lernen, also ist die Idee das (lassen Sie mich wissen, wenn das noch unklar ist): Die Abfrage zieht alle wöchentlichen Schichten des Benutzers. In den meisten Wochen sind Wochenenden frei, aber gelegentlich, und ohne jede echte Wenn es KEINE Wochenendschichten für ANYONE gibt, wird die Ausgabe ein MF-Plan sein. ABER wenn es geplante Verschiebungen für ANYONE gibt, ist die Ausgabe ein M-Sun-Plan. – Anthony

+0

Also, die Abfrage Im Grunde heißt das: "Wenn die Anzahl der Schichten am Samstag oder Sonntag dieser Woche = 0 ist, benutze 4 (also das Ende der Woche am Freitag), sonst mache es 6 (am Ende der Woche Sonntag). Also der Graf (*) erzeugt die 0 oder Null, die die IF() Funktion auslösen soll Verwenden Sie die 4, nicht die 6 für das Date_ADD – Anthony