599 Stimmen

Gibt es eine Max-Funktion in SQL Server, die zwei Werte wie Math.Max in .NET nimmt?

Ich möchte eine Abfrage wie diese schreiben:

SELECT o.OrderId, MAX(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o

Aber das ist nicht die Art und Weise, wie die MAX Funktion funktioniert, richtig? Es handelt sich um eine Aggregatfunktion, d. h. sie erwartet einen einzigen Parameter und gibt dann das MAX aller Zeilen zurück.

Weiß jemand, wie man es auf meine Art macht?

26 Stimmen

Das ist in den meisten anderen Datenbanken als GREATEST Funktion; SQLite emuliert die Unterstützung, indem es mehrere Spalten in der MAX Aggregat.

8 Stimmen

1 Stimmen

Bei der Suche nach einer Lösung für max(a, b) unten sollten Sie sich die Frage stellen, ob die Syntax oder die Berechnung für "a" und/oder "b" wiederholt werden soll. D.h. wenn "b" aus einer komplexen Berechnung mit viel Syntax abgeleitet wird, dann bevorzugen Sie vielleicht eine Lösung, bei der "b" nur einmal erscheint. Z.B. bedeutet die Lösung "IIF(a>b, a, b)" die Wiederholung von "b" - was syntaktisch hässlich sein könnte, aber die folgende Lösung bedeutet, dass "b" (und "a") nur einmal erscheint: SELECT MAX(WERT) FROM (SELECT a AS VALUE UNION SELECT b AS VALUE) AS T1

10voto

Lukasz Szozda Punkte 137580

JA, DAS GIBT ES.

T-SQL unterstützt jetzt GREATEST/LEAST-Funktionen:

MAX/MIN als NICHT-Aggregatfunktion

Dies ist jetzt für Azure SQL Database und SQL Managed Instance verfügbar. Sie wird in die nächste Version von SQL Server integriert.

Logische Funktionen - GREATEST (Transact-SQL)

Diese Funktion gibt den Maximalwert aus einer Liste von einem oder mehreren Ausdrücken zurück.

GREATEST ( expression1 [ ,...expressionN ] ) 

In diesem Fall also:

SELECT o.OrderId, GREATEST(o.NegotiatedPrice, o.SuggestedPrice)
FROM Order o

7 Stimmen

Usted wird nicht finden Sie diese Funktionen in SQL Server 2019 (150) oder früher.

1 Stimmen

Ich denke GREATEST ist derzeit nur auf SQL Server Azure verfügbar

9voto

Tom Arleth Punkte 153
SELECT o.OrderId,   
--MAX(o.NegotiatedPrice, o.SuggestedPrice)  
(SELECT MAX(v) FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) as ChoosenPrice  
FROM Order o

0 Stimmen

Eine Erklärung finden Sie in diesem Artikel: red-gate.com/simple-talk/sql/sql-training/

4 Stimmen

Bitte fügen Sie die benötigten Informationen nicht einfach durch einen Link in Ihren Code ein. Stellen Sie sich vor, dass dieser Link eines Tages abläuft und Ihre Antwort dann nutzlos sein wird. Fügen Sie also bitte die wesentlichen Informationen direkt in Ihre Antwort ein. Sie können den Link aber immer noch als Ressource für andere angeben, um weitere Informationen nachzuschlagen.

7voto

kristof Punkte 50991

Ich würde mich für die Lösung entscheiden, die von kcrumley Ändern Sie es einfach leicht, um NULLs zu behandeln

create function dbo.HigherArgumentOrNull(@val1 int, @val2 int)
returns int
as
begin
  if @val1 >= @val2
    return @val1
  if @val1 < @val2
    return @val2

 return NULL
end

EDITAR Geändert nach Kommentar von Mark . Wie er in der 3-wertigen Logik richtig bemerkt hat, sollte x > NULL oder x < NULL immer NULL ergeben. Mit anderen Worten: unbekanntes Ergebnis.

2 Stimmen

Nullen sind wichtig. Und es ist wichtig, sie konsequent zu behandeln. Die einzig richtige Antwort auf Is NULL > x ist NULL.

1 Stimmen

Sie haben Recht, ich werde meine Antwort entsprechend ändern, danke für den Hinweis.

1 Stimmen

Wenn wir einen int und einen NULL-Wert übergeben, dann denke ich, dass es üblicher ist, den Nicht-Null-Wert zurückgegeben haben zu wollen, so dass die Funktion als eine Kombination von Max(x,y) und ISNULL(x,y) fungiert. Daher würde ich persönlich die letzte Zeile wie folgt ändern: return ISNULL(@val1, @val2) - was zugegebenermaßen wahrscheinlich das ist, womit Sie anfangen mussten :)

6voto

SetFreeByTruth Punkte 801

SQL Server 2012 eingeführt IIF :

SELECT 
    o.OrderId, 
    IIF( ISNULL( o.NegotiatedPrice, 0 ) > ISNULL( o.SuggestedPrice, 0 ),
         o.NegotiatedPrice, 
         o.SuggestedPrice 
    )
FROM 
    Order o

Die Behandlung von NULLs wird empfohlen, wenn man IIF denn ein NULL auf beiden Seiten Ihres boolean_expression wird verursachen IIF zur Rückgabe der false_value (im Gegensatz zu NULL ).

0 Stimmen

Ihre Lösung wird NULL nicht gut behandeln, wenn der andere Wert negativ ist, wird dies null zurückgeben

5voto

Uri Abramson Punkte 5719

So einfach ist das:

CREATE FUNCTION InlineMax
(
    @p1 sql_variant,
    @p2 sql_variant
)  RETURNS sql_variant
AS
BEGIN
    RETURN CASE 
        WHEN @p1 IS NULL AND @p2 IS NOT NULL THEN @p2 
        WHEN @p2 IS NULL AND @p1 IS NOT NULL THEN @p1
        WHEN @p1 > @p2 THEN @p1
        ELSE @p2 END
END;

0 Stimmen

Siehe @Neil Kommentar zu einer früheren Antwort SELECT dbo.InlineMax(CAST(0.5 AS FLOAT), 100) ist falsch.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X