Existe-t-il une fonction Max dans SQL Server qui prend deux valeurs comme Math.Max ​​dans .NET?

488

Je veux écrire une requête comme celle-ci:

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

Mais ce n'est pas ainsi que la MAXfonction fonctionne, non? Il s'agit d'une fonction d'agrégation, elle attend donc un seul paramètre, puis retourne le MAX de toutes les lignes.

Est-ce que quelqu'un sait comment le faire à ma façon?

skb
la source
13
Cela est implémenté dans la plupart des autres bases de données en tant que GREATESTfonction; SQLite émule la prise en charge en autorisant plusieurs colonnes dans l' MAXagrégat.
OMG Ponies
7
Copie
Lorsque vous trouvez une solution pour max (a, b) ci-dessous, gardez à l'esprit la question de savoir si vous souhaitez que la syntaxe ou le calcul pour "a" et / ou "b" soit répété. C'est-à-dire que si "b" est dérivé d'un calcul complexe impliquant beaucoup de syntaxe, alors vous pouvez préférer une solution où "b" n'apparaît qu'une seule fois. Par exemple, la solution "IIF (a> b, a, b)" signifie la répétition de "b" - qui peut être syntaxiquement laid, mais la solution suivante signifie que "b" (et "a") n'apparaissent qu'une seule fois: SELECT MAX (VALEUR) FROM (SELECT a AS VALUE UNION SELECT b AS VALUE) AS T1
Andrew Jens

Réponses:

158

Vous auriez besoin de faire un User-Defined Functionsi vous vouliez avoir une syntaxe similaire à votre exemple, mais pourriez-vous faire ce que vous voulez faire, en ligne, assez facilement avec une CASEdéclaration, comme les autres l'ont dit.

Le UDFpourrait être quelque chose comme ceci:

create function dbo.InlineMax(@val1 int, @val2 int)
returns int
as
begin
  if @val1 > @val2
    return @val1
  return isnull(@val2,@val1)
end

... et tu appellerais ça comme ça ...

SELECT o.OrderId, dbo.InlineMax(o.NegotiatedPrice, o.SuggestedPrice) 
FROM Order o
Kevin Crumley
la source
25
Je soutiendrais votre solution, la seule chose que j'ajouterais est la prise en charge des valeurs NULL. Si vous modifiez simplement la dernière ligne: "return @ value2" pour lire comme: "return isnull (@ val2, @ val1)", alors si l'une des valeurs est nulle, la fonction renverra la valeur non nulle, sinon elle fonctionnera comme normal
kristof
1
Qu'en est-il des autres types de données, par exemple, aurais-je besoin d'écrire un HigherIntegerArgument et un HigherDateTimeArgument et un HigherVarcharArgument et un ...?
onedaywhen
9
ce sera incroyablement lent, comme toutes les choses UDF scalaires. Utilisez des UDF en ligne à la place
AK
12
@xan Je n'ai aucune idée de ce qui m'est venu à l'esprit lorsque j'ai posé cette question. Pas trop, évidemment. Merci pour la réponse quand même.
Thomas
13
@Thomas Image de meme obligatoire (aucune infraction ne vous est destinée en aucune façon!) Flickr.com/photos/16201371@N00/2375571206
xan
468

Si vous utilisez SQL Server 2008 (ou supérieur), voici la meilleure solution:

SELECT o.OrderId,
       (SELECT MAX(Price)
        FROM (VALUES (o.NegotiatedPrice),(o.SuggestedPrice)) AS AllPrices(Price))
FROM Order o

Tous les crédits et votes devraient aller à la réponse de Sven à une question connexe, "SQL MAX de plusieurs colonnes?"
Je dis que c'est la " meilleure réponse " car:

  1. Cela ne nécessite pas de compliquer votre code avec les déclarations UNION, PIVOT, UNPIVOT, UDF et folles.
  2. Il n'est pas en proie au problème de la gestion des valeurs nulles, il les gère très bien.
  3. Il est facile de remplacer le "MAX" par "MIN", "AVG" ou "SUM". Vous pouvez utiliser n'importe quelle fonction d'agrégation pour rechercher l'agrégat sur de nombreuses colonnes différentes.
  4. Vous n'êtes pas limité aux noms que j'ai utilisés (c'est-à-dire "AllPrices" et "Price"). Vous pouvez choisir vos propres noms pour le rendre plus facile à lire et à comprendre pour le prochain gars.
  5. Vous pouvez trouver plusieurs agrégats à l'aide des tables dérivées de SQL Server 2008 comme suit :
    SELECT MAX (a), MAX (b) FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10)) COMME MyTable (a, b)
MikeTeeVee
la source
27
+1 seule réponse qui ne nécessite pas d'accès pour créer des procédures / fonctions!
Alex
6
Exactement le type de réponse que je cherchais. L'utilisation des fonctions est lente et cela fonctionnera également sur les dates, ce dont j'ai besoin.
Johann Strydom
3
+1 Fonctionne parfaitement, surtout pour plus de 2 colonnes à comparer!
JanW
11
C'est moins performant que la solution CASE WHEN qui n'a besoin que de calculer un scalaire.
tekumara
5
Alors que la syntaxe plus simple ne vaut peut-être jamais la performance atteinte lors de la détermination du MAX de 2 valeurs, il peut en être autrement avec plus de valeurs. Même lors de l'obtention du MAX de 4 valeurs, les clauses CASE deviennent longues, maladroites et sujettes aux erreurs si elles sont générées à la main alors que la clause VALUES reste simple et claire.
Typhlosaurus
221

Peut se faire en une seule ligne:

-- the following expression calculates ==> max(@val1, @val2)
SELECT 0.5 * ((@val1 + @val2) + ABS(@val1 - @val2)) 

Edit: Si vous avez affaire à de très grands nombres, vous devrez convertir les variables de valeur en bigint afin d'éviter un débordement d'entier.

splattne
la source
18
+1 Je pense que vous avez fourni la méthode la plus correcte. "SELECT ((@ val1 + @ val2) + ABS (@ val1- @ val2)) / 2 comme MAX_OF_TWO" Rappelez-vous également, "SELECT ((@ val1 + @ val2) - ABS (@ val1- @ val2)) / 2 comme MIN_OF_TWO ".
tom
6
Cette façon donnera une erreur de dépassement si la somme est supérieure à ce qui peut être stocké dans un int: declare @ val1 int declare @ val2 int set @ val1 = 1500000000 set @ val2 = 1500000000 SELECT 0,5 * ((@ val1 + @ val2) + ABS (@ val1 - @ val2)) - => erreur de débordement
AakashM
89
C'est un "truc" extrêmement "sale". Lors de la programmation, votre code doit exprimer explicitement le but, mais dans votre cas, il ressemble à du code provenant d'un concours d'obscurcissement.
greenoldman
24
Il peut être "sale", mais ce pourrait être la seule option pour les bases de données avec des dialectes SQL simples.
splattne
12
Je ne suis pas d'accord avec Marcias. Le code n'a pas nécessairement lui-même besoin d'exprimer explicitement le but, tant que les commentaires permettent de le résoudre. Si vous faites des équations mathématiques complexes dans le code (ou n'importe où), il est parfois difficile de le rendre auto-descriptif. Tant qu'il est divisé en parties plus simples et plus faciles à comprendre, c'est une programmation correcte.
Rob
127

Je ne pense pas. Je le voulais l'autre jour. Le plus proche que j'ai obtenu était:

SELECT
  o.OrderId,
  CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN o.NegotiatedPrice 
     ELSE o.SuggestedPrice
  END
FROM Order o
Scott Langham
la source
4
Ceci est ma méthode préférée. Vous ne risquez pas un débordement, et c'est moins cryptique que la solution de splattne (qui est cool btw), et je n'ai pas les tracas de créer un UDF. le cas est très pratique dans de nombreuses situations.
Lance Fisher
SELECT o.OrderId, CAS WHEN o.NegotiatedPrice> o.SuggestedPrice OR o.SuggestedPrice IS NULL THEN o o.NegotiatedPrice ELSE o.SuggestedPrice END OF Order o
mohghaderi
Lorsque, au lieu de "o.NegotiatedPrice", vous avez plutôt un terme comme "(datiff (jour, convertir (datetime, adr_known_since, 120), getdate ()) - 5) * 0.3", vous devez répéter ce code. Toute modification future du terme devra être effectuée deux fois. Une fonction de type min (x, y, ...) serait beaucoup plus agréable
Daniel
87

Pourquoi ne pas essayer la fonction IIF (nécessite SQL Server 2012 et versions ultérieures)

IIF(a>b, a, b)

C'est ça.

(Astuce: soyez prudent dans les deux cas null, car le résultat de a>bsera faux chaque fois que l'un ou l'autre est nul. Il en bsera de même dans ce cas)

Xin
la source
7
Si l'une des valeurs est NULL, le résultat sera toujours le second.
jahu
4
IIF () est le sucre syntaxique de l'instruction CASE. Si l'une des valeurs du conditionnel CASE est NULL, le résultat sera le second (ELSE).
xxyzzy
@xxyzzy parce que la NULL > 1234déclaration est fausse
Xin
8
donc IIF(a>b, a, COALESCE(b,a))donner la valeur quand il n'y en a qu'une
mpag
32
DECLARE @MAX INT
@MAX = (SELECT MAX(VALUE) 
               FROM (SELECT 1 AS VALUE UNION 
                     SELECT 2 AS VALUE) AS T1)
jbeanky
la source
Je donne à cette solution un +1 car elle est conforme à DRY (ne vous répétez pas) sans avoir besoin d'écrire un UDF. C'est aussi très bien si les deux valeurs que vous devez vérifier sont les résultats d'autres sql, par exemple dans mon cas, je veux trouver la plus grande des 2 instructions select count (*).
MikeKulls
1
Je déteste devoir recourir à cette solution, mais c'est certainement la meilleure façon de le faire dans SQL Server jusqu'à ce qu'ils ajoutent une prise en charge native de GREATEST ou en ligne MAX. Merci de l'avoir posté - +1 pour vous!
SqlRyan
10

Les autres réponses sont bonnes, mais si vous devez vous soucier d'avoir des valeurs NULL, vous voudrez peut-être cette variante:

SELECT o.OrderId, 
   CASE WHEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice) > ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
        THEN ISNULL(o.NegotiatedPrice, o.SuggestedPrice)
        ELSE ISNULL(o.SuggestedPrice, o.NegotiatedPrice)
   END
FROM Order o

la source
1
Le seul ISNULL requis est après le ELSE. La comparaison ">" initiale renvoie false et passe à ELSE si l'une des valeurs est déjà nulle.
Phil B
10

Dans SQL Server 2012 ou version ultérieure, vous pouvez utiliser une combinaison de IIFet ISNULL(ou COALESCE) pour obtenir le maximum de 2 valeurs.
Même lorsque l'un d'eux est NULL.

IIF(col1 >= col2, col1, ISNULL(col2, col1)) 

Ou si vous voulez qu'il renvoie 0 lorsque les deux sont NULL

IIF(col1 >= col2, col1, COALESCE(col2, col1, 0)) 

Exemple d'extrait:

-- use table variable for testing purposes
declare @Order table 
(
  OrderId int primary key identity(1,1),
  NegotiatedPrice decimal(10,2),
  SuggestedPrice decimal(10,2)
);

-- Sample data
insert into @Order (NegotiatedPrice, SuggestedPrice) values
(0, 1),
(2, 1),
(3, null),
(null, 4);

-- Query
SELECT 
     o.OrderId, o.NegotiatedPrice, o.SuggestedPrice, 
     IIF(o.NegotiatedPrice >= o.SuggestedPrice, o.NegotiatedPrice, ISNULL(o.SuggestedPrice, o.NegotiatedPrice)) AS MaxPrice
FROM @Order o

Résultat:

OrderId NegotiatedPrice SuggestedPrice  MaxPrice
1       0,00            1,00            1,00
2       2,00            1,00            2,00
3       3,00            NULL            3,00
4       NULL            4,00            4,00

Mais si l'on doit additionner plusieurs valeurs?
Ensuite, je suggère de CROSS APPLIQUER à une agrégation des VALEURS.
Cela a également l'avantage de pouvoir calculer d'autres choses en même temps.

Exemple:

SELECT t.*
, ca.[Total]
, ca.[Maximum]
, ca.[Minimum]
, ca.[Average]
FROM SomeTable t
CROSS APPLY (
   SELECT 
    SUM(v.col) AS [Total], 
    MIN(v.col) AS [Minimum], 
    MAX(v.col) AS [Maximum], 
    AVG(v.col) AS [Average]
   FROM (VALUES (t.Col1), (t.Col2), (t.Col3), (t.Col4)) v(col)
) ca
LukStorms
la source
8

Les sous-requêtes peuvent accéder aux colonnes à partir de la requête externe, vous pouvez donc utiliser cette approche pour utiliser des agrégats tels que MAXsur plusieurs colonnes. (Probablement plus utile quand il y a un plus grand nombre de colonnes impliquées)

;WITH [Order] AS
(
SELECT 1 AS OrderId, 100 AS NegotiatedPrice, 110 AS SuggestedPrice UNION ALL
SELECT 2 AS OrderId, 1000 AS NegotiatedPrice, 50 AS SuggestedPrice
)
SELECT
       o.OrderId, 
       (SELECT MAX(price)FROM 
           (SELECT o.NegotiatedPrice AS price 
            UNION ALL SELECT o.SuggestedPrice) d) 
        AS MaxPrice 
FROM  [Order]  o
Martin Smith
la source
Agréable! Il évolue très bien.
greenoldman
+1 pour montrer l'amour pour ceux qui sont encore en 2005. Je ne sais pas comment j'ai négligé cette réponse. Sous les couvertures, j'imagine qu'il fonctionne aussi bien que ce que j'ai publié 2 ans plus tard. Rétrospectivement, j'aurais dû m'en rendre compte et mettre à jour votre réponse pour inclure la nouvelle syntaxe 2008 à l'époque. Désolé, j'aimerais pouvoir partager mes points avec vous maintenant.
MikeTeeVee
@MikeTeeVee - Merci! Oui sous les couvertures, le plan sera le même. Mais la VALUESsyntaxe est plus agréable.
Martin Smith
6

SQL Server 2012 a introduit IIF:

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

La manipulation des valeurs NULL est recommandée lors de l'utilisation IIF, car un NULLde chaque côté de votre boolean_expressionvolonté provoquera IIFle retour de false_value(par opposition à NULL).

SetFreeByTruth
la source
Votre solution ne gérera pas bien NULL lorsque l'autre valeur est négative, cela renverra null
t-clausen.dk
5

J'irais avec la solution fournie par kcrumley Il suffit de la modifier légèrement pour gérer les NULLs

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

EDIT Modifié après commentaire de Mark . Comme il l'a correctement souligné dans 3 logiques de valeur, x> NULL ou x <NULL doit toujours retourner NULL. En d'autres termes, résultat inconnu.

kristof
la source
1
Les nuls sont importants. Et il est important de les gérer de manière cohérente. La seule bonne réponse à Is NULL> x est NULL.
Mark Brackett
Vous avez raison, je vais modifier ma réponse pour refléter cela, merci de l'avoir signalé
kristof
Si nous passons un int et un NULL, je pense qu'il est plus courant de vouloir que la valeur non nulle soit renvoyée, donc la fonction agit comme une combinaison de Max (x, y) et ISNULL (x, y). Par conséquent, je changerais personnellement la dernière ligne: return ISNULL (@ val1, @ val2) - ce qui, il est vrai, est probablement ce avec quoi vous deviez commencer :)
redcalx
@ the-locster, voir le commentaire de Mark
kristof
1
ce sera incroyablement lent, comme toutes les choses UDF scalaires. Utilisez des UDF en ligne à la place
AK
4

C'est aussi simple que cela:

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;
Uri Abramson
la source
Voir le commentaire @Neil d'une réponse précédente SELECT dbo.InlineMax (CAST (0.5 AS FLOAT), 100) est incorrect.
Luca
4
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
Tom Arleth
la source
Pour des explications, veuillez consulter cet article: red-gate.com/simple-talk/sql/sql-training/…
Tom Arleth
2
Veuillez ne pas inclure les informations nécessaires à votre code simplement par un lien. Imaginez que ce lien expire un jour et que votre réponse sera alors inutile. Veuillez donc continuer et ajouter les informations essentielles directement dans votre réponse. Mais vous pouvez toujours fournir ce lien comme ressource pour que d'autres puissent rechercher des informations supplémentaires.
L. Guthardt
3

Oups, je viens de poster une dupe de cette question ...

La réponse est qu'il n'y a pas de fonction intégrée comme Oracle's Greatest , mais vous pouvez obtenir un résultat similaire pour 2 colonnes avec un UDF, notez que l'utilisation de sql_variant est assez importante ici.

create table #t (a int, b int) 

insert #t
select 1,2 union all 
select 3,4 union all
select 5,2

-- option 1 - A case statement
select case when a > b then a else b end
from #t

-- option 2 - A union statement 
select a from #t where a >= b 
union all 
select b from #t where b > a 

-- option 3 - A udf
create function dbo.GREATEST
( 
    @a as sql_variant,
    @b as sql_variant
)
returns sql_variant
begin   
    declare @max sql_variant 
    if @a is null or @b is null return null
    if @b > @a return @b  
    return @a 
end


select dbo.GREATEST(a,b)
from #t

kristof

Publié cette réponse:

create table #t (id int IDENTITY(1,1), a int, b int)
insert #t
select 1,2 union all
select 3,4 union all
select 5,2

select id, max(val)
from #t
    unpivot (val for col in (a, b)) as unpvt
group by id
Sam Saffron
la source
1
Remarque: l'implémentation de la fonction GREATEST correspondra au comportement Oracle pour 2 paramètres, si un paramètre est nul, il retournera null
Sam Saffron
2
Vous devez être prudent lorsque vous utilisez sql_variant. Votre fonction donnera un résultat inattendu dans la situation suivante: SELECT dbo.greatest (CAST (0.5 AS FLOAT), 100)
Neil
@Neil a raison (je l'ai appris à la dure), comment amélioreriez-vous cette fonction pour éviter ce genre de problèmes?
Luca
3

Voici un exemple de cas qui devrait gérer les valeurs nulles et fonctionnera avec les anciennes versions de MSSQL. Ceci est basé sur la fonction inline dans l'un des exemples populaires:

case
  when a >= b then a
  else isnull(b,a)
end
scradam
la source
2

Je ne le ferais probablement pas de cette façon, car il est moins efficace que les constructions CASE déjà mentionnées - sauf si, peut-être, vous aviez des index de couverture pour les deux requêtes. Quoi qu'il en soit, c'est une technique utile pour des problèmes similaires:

SELECT OrderId, MAX(Price) as Price FROM (
   SELECT o.OrderId, o.NegotiatedPrice as Price FROM Order o
   UNION ALL
   SELECT o.OrderId, o.SuggestedPrice as Price FROM Order o
) as A
GROUP BY OrderId
Mark Brackett
la source
2

Pour la réponse ci-dessus concernant les grands nombres, vous pouvez faire la multiplication avant l'addition / soustraction. C'est un peu plus volumineux mais ne nécessite aucun casting. (Je ne peux pas parler de vitesse mais je suppose que c'est toujours assez rapide)

SELECT 0,5 * ((@ val1 + @ val2) + ABS (@ val1 - @ val2))

Modifications apportées à

SELECT @ val1 * 0.5 + @ val2 * 0.5 + ABS (@ val1 * 0.5 - @ val2 * 0.5)

au moins une alternative si vous voulez éviter de lancer.

deepee1
la source
2

Voici une version IIF avec une gestion NULL (basée sur la réponse de Xin):

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a > b, a, b))

La logique est la suivante, si l'une des valeurs est NULL, retourne celle qui n'est pas NULL (si les deux sont NULL, un NULL est retourné). Sinon, renvoyez le plus grand.

La même chose peut être faite pour MIN.

IIF(a IS NULL OR b IS NULL, ISNULL(a,b), IIF(a < b, a, b))
jahu
la source
1

Vous pouvez faire quelque chose comme ça:

select case when o.NegotiatedPrice > o.SuggestedPrice 
then o.NegotiatedPrice
else o.SuggestedPrice
end
Per Hornshøj-Schierbeck
la source
1
SELECT o.OrderID
CASE WHEN o.NegotiatedPrice > o.SuggestedPrice THEN
 o.NegotiatedPrice
ELSE
 o.SuggestedPrice
END AS Price
Wayne
la source
1
CREATE FUNCTION [dbo].[fnMax] (@p1 INT, @p2 INT)
RETURNS INT
AS BEGIN

    DECLARE @Result INT

    SET @p2 = COALESCE(@p2, @p1)

    SELECT
        @Result = (
                   SELECT
                    CASE WHEN @p1 > @p2 THEN @p1
                         ELSE @p2
                    END
                  )

    RETURN @Result

END
andrewc
la source
1

Dans sa forme la plus simple ...

CREATE FUNCTION fnGreatestInt (@Int1 int, @Int2 int )
RETURNS int
AS
BEGIN

    IF @Int1 >= ISNULL(@Int2,@Int1)
        RETURN @Int1
    ELSE
        RETURN @Int2

    RETURN NULL --Never Hit

END
jsmink
la source
1

Pour SQL Server 2012:

SELECT 
    o.OrderId, 
    IIF( o.NegotiatedPrice >= o.SuggestedPrice,
         o.NegotiatedPrice, 
         ISNULL(o.SuggestedPrice, o.NegiatedPrice) 
    )
FROM 
    Order o
Steve Ford
la source
1

Voici la réponse de @Scott Langham avec une gestion NULL simple:

SELECT
      o.OrderId,
      CASE WHEN (o.NegotiatedPrice > o.SuggestedPrice OR o.SuggestedPrice IS NULL) 
         THEN o.NegotiatedPrice 
         ELSE o.SuggestedPrice
      END As MaxPrice
FROM Order o
mohghaderi
la source
0
select OrderId, (
    select max([Price]) from (
        select NegotiatedPrice [Price]
        union all
        select SuggestedPrice
    ) p
) from [Order]
Erreur
la source
0
 -- Simple way without "functions" or "IF" or "CASE"
 -- Query to select maximum value
 SELECT o.OrderId
  ,(SELECT MAX(v)
   FROM (VALUES (o.NegotiatedPrice), (o.SuggestedPrice)) AS value(v)) AS MaxValue
  FROM Order o;
ashraf mohammed
la source
Bien que l'utilisation intéressante de l' VALUESinline comme ça, je ne suis pas sûr que ce soit plus simple que CASEou IFF. Je serais intéressé de voir comment les performances de cette solution se comparent aux autres options
Chris Schaller
0

En développant la réponse de Xin et en supposant que le type de valeur de comparaison est INT, cette approche fonctionne également:

SELECT IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)

Il s'agit d'un test complet avec des exemples de valeurs:

DECLARE @A AS INT
DECLARE @B AS INT

SELECT  @A = 2, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2

SELECT  @A = 2, @B = 3
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 3

SELECT  @A = 2, @B = NULL
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 2    

SELECT  @A = NULL, @B = 1
SELECT  IIF(ISNULL(@A, -2147483648) > ISNULL(@B, -2147483648), @A, @B)
-- 1
Chris Porter
la source
0

Dans MemSQL, procédez comme suit:

-- DROP FUNCTION IF EXISTS InlineMax;
DELIMITER //
CREATE FUNCTION InlineMax(val1 INT, val2 INT) RETURNS INT AS
DECLARE
  val3 INT = 0;
BEGIN
 IF val1 > val2 THEN
   RETURN val1;
 ELSE
   RETURN val2;
 END IF; 
END //
DELIMITER ;

SELECT InlineMax(1,2) as test;
Aigle du désert
la source
-1

Dans Presto, vous pouvez utiliser

SELECT array_max(ARRAY[o.NegotiatedPrice, o.SuggestedPrice])
maxymoo
la source