Ich möchte nach allen Datensätzen suchen, die an bestimmten Daten auftreten.
SELECT *
FROM table1
WHERE date(column) in ($date1, $date2, ...);
Wie viele von Ihnen jedoch wissen, verträgt sich diese Art von Vergleich nicht mit Indizes. Ich habe mich also gefragt, ob es eine einfache Möglichkeit gibt, diese Abfrage ohne großen Aufwand in etwas im Stil der folgenden Abfrage zu konvertieren (dh: kein externes Tool verwenden).
SELECT *
FROM table1
WHERE (column >= $date1 AND column < $date1 + interval 1 day)
OR (column >= $date2 AND column < $date2 + interval 1 day)
...
Der Optimierer kann also weiterhin die Indizes verwenden. (Ich benutze MySQL, aber ANSI SQL wäre großartig)
mysql
query-performance
date
condition
msemelman
quelle
quelle
date()
Funktion (anscheinend zum Konvertierencolumn
in dendate
Datentyp), während Sie dies in der zweiten Abfrage nicht tun, und dann sagen Sie, dass die Verwendung vondate()
"Indizes bricht". Warum verwenden Sie es überhaupt, wenn es (wie aus der zweiten Abfrage hervorgeht) nicht erforderlich ist?Antworten:
VORSCHLAG # 1
VORSCHLAG # 2
quelle
Versuchen Sie so etwas: (Ich habe dies unter Oracle gemacht, es sollte meistens woanders funktionieren. Die WITH-Klauseln dienen hauptsächlich dazu, nur Beispieldaten zu fälschen. Also nicht unbedingt notwendig.)
Ergebnisse:
Dies könnte "verallgemeinert" werden als:
Das sollte auf jeder Datenbank funktionieren ... MYSQL, Oracle, was auch immer.
Sie müssen nur den Datumslistenbereich eingeben - es ist am besten, ihn als eine andere Tabelle oder so einzugeben ...
Ich könnte zeigen, wie es geht Oracle, aber wahrscheinlich nicht besonders nützlich für Sie :) Könnte eine andere Frage dafür brauchen, wenn nötig.
quelle
with
.nvl()
undto_date()
sind proprietäre Oracle-Funktionen.with
undlead()
undover
sind Standard-SQL, aber nicht in MySQL implementiert. Diese Antwort mag für Oracle in Ordnung sein, erfordert jedoch erhebliche Änderungen und Anstrengungen, damit sie in MySQL funktioniert. Nurdual
würde so funktionieren wie es ist (obwohl es eine andere nicht standardmäßige Funktion ist.)between
ist das einfach falsch. Das OP wurde korrekt verwendet>=
und<
in der Frage gibt es keinen Grund, es zu ändern. Und ich verstehe nicht, warum wirlead()
sowieso verwenden müssen. Es scheint zu ändern, was das OP zu etwas anderem will.Ich stimme dem zweiten Vorschlag von RolandoMySQLDBA zu, dass die Suche nach den Ergebnissen zu schnell ist,
UNION
anstatt sieOR
zu verwenden. Und wir wissen auch:Und als Ihre Anforderung denke ich, dass Ihre Daten in einer separaten Reihenfolge vorliegen, in der keine doppelte Zeile erstellt wird. Um das Entfernen doppelter Zeilen zu vermeiden , die eine versteckte Reihenfolge von und usw. enthalten, empfehle ich Ihnen,
UNION ALL
anstelle von Folgendes zu verwendenUNION
: so was:quelle