2012-04-03 10 views
0

Ich habe diese, wo params, aber es ist der Rückkehr nicht das, was gewünscht ist:Ändern MySQL WHERE params

WHERE `Profiles`.`Departure1` >= '2012-04-01' 
OR `Profiles`.`Departure2` >= '2012-04-01' 
OR `Profiles`.`Departure3` >= '2012-04-01' 
AND `Profiles`.`Departure1` <= '2012-04-04' 
OR `Profiles`.`Departure2` <= '2012-04-04' 
OR `Profiles`.`Departure3` <= '2012-04-04' 

Es gibt drei Abfahrts Felder Datum und ich versuche nur Einträge zurück, wo das Datum Land zwischen den beiden Termine. Was ich hier habe, ist alles zurückzugeben. Gibt es einen besseren Weg dies zu tun, der tatsächlich funktionieren könnte?

+0

Ein bisschen unklar. "Das Datum" bedeutet das heutige Datum? Auch Sie erwähnen 3 Daten, aber sagen "zwischen den beiden Daten". Welche zwei? –

Antwort

3

Verwenden Sie eine korrekte Klammer:

WHERE ((`Profiles`.`Departure1` >= '2012-04-01' 
OR `Profiles`.`Departure2` >= '2012-04-01' 
OR `Profiles`.`Departure3` >= '2012-04-01') 
AND (`Profiles`.`Departure1` <= '2012-04-04' 
OR `Profiles`.`Departure2` <= '2012-04-04' 
OR `Profiles`.`Departure3` <= '2012-04-04')) 
0

Es gibt viele Möglichkeiten, diese sauberer zu bekommen, aber ich habe es lange Hand zu zeigen, das Problem mit der Abfrage oben gehalten.

Sie müssen eine Verbindung zwischen den Gruppen von Abfahrtsdaten herstellen, die obige ist zu breit.

WHERE (Profiles. Departure1> = '2012-04-01' AND Profiles. Departure1 < = '2012-04-04') OR (Profiles. Departure2> = '2012-04-01' AND Profiles . Departure2 < = '2012-04-04') OR (Profiles. Departure3> = '2012-04-01' AND Profiles. Departure3 < = '2012-04-04'

BETWEEN
4

Verwenden MySQLs) Betreiber :

WHERE 
    `Profiles`.`Departure1` BETWEEN CAST('2012-04-01' AS Date) AND CAST('2012-04-04' AS Date) OR 
    `Profiles`.`Departure2` BETWEEN CAST('2012-04-01' AS Date) AND CAST('2012-04-04' AS Date) OR 
    `Profiles`.`Departure3` BETWEEN CAST('2012-04-01' AS Date) AND CAST('2012-04-04' AS Date) 

Lesen Sie die Dokumentation:

A Hinweis: Wenn dies ist die Art der Sache, du gehst zu sein Wenn Sie eine Menge davon tun, sollten Sie Ihre Daten als UNIX-Zeitstempel speichern und stattdessen den Feldtyp BIGINT verwenden als ein Date. Auf diese Weise müssen Sie nicht CAST so viel zu tun BETWEEN Vergleiche verwenden. Sie können FROM_UNIXTIME (docs) verwenden, um auf dem Weg aus der Datenbank zu formatieren, anstatt bei jedem Vergleich mit der Konvertierung zu experimentieren. Siehe:

+0

Sie müssen überhaupt nicht casten. Tun Sie einfach "date_field BETWEEN" 2012-01-01 "und" 2012-01-10 "'. Darüber hinaus ist es nicht erforderlich, das Feld DATUM so zu konvertieren, dass Zeitstempel berücksichtigt werden, da Datumsbereichsscans [auf DATE-Feldern schneller als auf INTs] sind (http://www.dbtuna.com/article.php?id=36). Man muss jedoch vorsichtig mit DATETIME-Feldern sein, da, wenn Sie BETWEEN auf diesen verwenden, es das letzte Datum "ausschließen" wird, denn für "BETWEEN" 2000-01-01 "UND" 2000-01-10 "" wird BETWEEN "2000-01-01 00:00:00" UND "2000-01-10 00:00:00" technisch ausführen. Stellen Sie also sicher, dass Sie korrekte Schließzeiten von "23:59:59" definieren. – Andris

+0

Danke für die Bemerkungen! Der Artikel, den Sie bezüglich des Benchmarks verlinken, scheint sich nicht mit "INT" zu befassen, sondern mit "TIMESTAMP" gegenüber "DATE". Aus der Beschreibung des Handbuchs zur Mechanik von 'TIMESTAMP' bin ich nicht überrascht, dass es langsamer ist als 'DATE', aber ich würde" INT "fragen, dass es langsamer ist. Soweit ich nicht 'CAST' brauche, mag ich keine implizite Konvertierung, auch wenn es eingebacken ist. Ich werde immer explizites Typecasting verwenden, weil ich denke, dass es für einen direkteren und expressiveren Code sorgt - Sie wissen, was der Entwickler macht erwartet, weil ich genau so codiert habe. IMO, desto weniger Mehrdeutigkeit, desto besser. –