Nach Prüfung dieser Frage scheint dies eine Menge Arbeit zu sein, die nicht benötigt werden sollte. Sie versuchen, eine Reichweite mit einem Datum zu erweitern. In anderen Datenbanken würden Sie nur greatest
und verwenden least
.
least(extendDate,min), greatest(extendDate,max)
Wenn ich versuche, diese zu verwenden, bekomme ich
'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
Das würde die Ausdehnung in beide Richtungen abdecken.
Für die Zwecke der Frage müssten Sie immer noch einen exklusiven Bereichsaustausch durchführen.
Ich frage mich nur, wie SQL Server-Benutzer Abfragemuster implementieren, um Nachahmung least
und greatest
Funktionalität zu erzielen .
- PostgreSQL
GREATEST
/LEAST
- MySQL
GREATEST
/LEAST
- MariaDB
GREATEST
LEAST
- DB2
GREATEST
LEAST
- Orakel
GREATEST
LEAST
Entrollen Sie die Bedingungen in CASE
Anweisungen oder gibt es eine Erweiterung, ein Add-On eines Drittanbieters oder eine Lizenz von Microsoft, die diese Funktionalität ermöglicht?
sql-server
t-sql
feature-comparison
Evan Carroll
quelle
quelle
LEAST
/GREATEST
functions hat - fast alle RDBMS-Konkurrenten haben mindestens Äquivalente. Die einzige Ausnahme, die ich finden konnte, ist Sybase, aber das wird auch seit vielen Jahren eingestellt.Antworten:
Eine gebräuchliche Methode besteht darin, die
VALUES
Klausel zu verwenden undCROSS APPLY
die beiden Spalten als eine einzige Spalte zu aliasieren und dann dasMIN
undMAX
von jeder abzurufen .Es gibt andere Möglichkeiten, es zu schreiben, zum Beispiel mit
UNION ALL
Die resultierenden Abfragepläne scheinen jedoch identisch zu sein.
quelle
Sie können die Werte auch in eine Unterabfrage einfügen. So was:
quelle
Das wäre ein guter Anfang -
quelle
MINDESTENS Äquivalent:
GRÖSSTES Äquivalent:
quelle
least(5,6,7,8,9)
?Ich erstelle benutzerdefinierte Funktionen, z
Obwohl dies in einfachen Fällen möglich ist, gibt es bei diesem Ansatz mehrere Probleme:
least
Operator in Oracle und MySQL tut, unterscheidet sich jedoch von Postgres. Aber diese Panzerung gegen Null macht es ausführlicher (wenn Sie wissen, dass sie nicht null sind, würde eine Ebenecase when @a <= @b then @a else @b end
funktionieren).Alles in allem kann es besser sein, die
case
Erklärung mit der Hand aufzuschreiben, wenn es um Leistung geht. Ich habe sogar versucht, geschachteltecase
Anweisungen auf der Clientseite zu generieren, wenn mehrere Werte verglichen werden müssen.quelle
Ich hatte vor, @ ed-avis zu kommentieren, konnte dies aber aufgrund mangelnder Reputation nicht tun und habe dies daher als Erweiterung seiner Antwort veröffentlicht.
Ich habe den Nachteil beseitigt, dass "ärgerlicherweise für jeden Datentyp separate Funktionen erstellt werden müssen". Verwenden von SQL_VARIANT .
Hier ist meine Implementierung:
Auch diese Funktion behandelt NULL- Werte wie die postgresql-Version.
Diese Funktion könnte der Einfachheit halber zu DB hinzugefügt werden, ist jedoch zehnmal langsamer als die Verwendung der integrierten Funktion
IIF
. Meine Tests zeigen, dass eine solche Funktion mit genauem Typ ( datetime ) dasselbe wie die Version von sql_variant ausführt .PS Ich führe einige Tests mit einem Datensatz von 350k Werten durch und scheine, dass die Leistung gleich ist, sql_variant ist ein bisschen schneller, aber ich glaube, es ist nur Jitter.
Aber in jedem Fall ist die IIF-Version 10- mal schneller !!!
Ich habe Inline nicht getestet,
CASE WHEN
aber im Grunde genommen ist für t-sql IIF dasselbe wie case , und wenn es vom Optimierer in case-Ausdruck konvertiert wird.SCHLUSSFOLGERUNG: Die Verwendung von IIF ist schneller, wenn es auf die Leistung ankommt, aber für das Prototyping oder wenn mehr Code-Klarheit erforderlich ist und keine großen Berechnungen erforderlich sind, sofern die Funktion verwendet werden kann.
quelle
iif(a<b, a, b)
ist zehnmal schneller als jede benutzerdefinierte Funktion.IIF()
- schneller als die Verwendung einesCASE
Ausdrucks? Mein Punkt ist, dass Sie, da Sie sich mit Leistungstests befasst haben, alle vorgeschlagenen Methoden / Antworten testen sollten.