web-dev-qa-db-fra.com

Comment calculer le maximum de deux nombres dans Oracle SQL select?

Cela devrait être simple et montre mon ignorance de SQL:

SQL> select max(1,2) from dual;
select max(1,2) from dual
       *
ERROR at line 1:
ORA-00909: invalid number of arguments

Je sais que max est normalement utilisé pour les agrégats. Que puis-je utiliser ici? 

En fin de compte, je veux utiliser quelque chose comme

select total/max(1,number_of_items) from xxx;

où number_of_items est un entier et peut être 0. Je veux voir le total également dans ce cas.

24
Peter G.

Vous pouvez utiliser une instruction CASE

SELECT Total = CASE WHEN number_of_items > 0 
               THEN total/number_of_items
               ELSE total END
FROM   xxx
15
Lieven Keersmaekers

On dirait que vous utilisez Oracle, vous pouvez donc utiliser la fonction greatest à la place de max

select total/greatest(1,number_of_items) 
from xxx;
64
Martin Smith
SELECT total/(CASE WHEN number_of_items>1 THEN number_of_items ELSE 1) FROM xxx

devrait travailler ici .... 

3
Hari Menon

Vous devrez créer une nouvelle fonction pour 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;

Consultez ce fil pour plus de détails: Existe-t-il une fonction Max dans SQL Server qui prend deux valeurs telles que Math.Max ​​dans .NET?

2
Uri Abramson

Normalement ce serait:

SELECT MAX(columnName)
FROM   Table1

Ou

SELECT MAX(columnName)
FROM   (SELECT * FROM TableX) AS T1

Ou (et ce serait probablement ce que vous voulez dans votre cas)

SELECT MAX(value)
FROM   (SELECT 1 AS VALUE FROM DUAL UNION SELECT 2 AS VALUE FROM DUAL)

Il peut y avoir une façon plus propre de le faire cependant.

UPDATE: En utilisant votre exemple de number_of_items et total de la table XXX, ce serait:

SELECT TOTAL/MAX(NUMBER_OF_ITEMS)
FROM   XXX

UPDATE 2: N'oubliez pas que si vous autorisez le nombre d'éléments à 0, vous obtiendrez une exception de division par 0. C'est pourquoi, dans l'autre réponse, l'utilisateur plaçait un cas et le reste était le TOTAL, de cette façon vous n'obtenez pas cette exception.

2
XstreamINsanity

Il est possible de faire cela dans Oracle 8.0 et versions antérieures (c'est-à-dire avant que CASE ne soit introduit) avec l'astuce mathématique suivante:

SELECT DECODE(NUMBER_OF_ITEMS-1+ABS(NUMBER_OF_ITEMS-1), 0, 1, NUMBER_OF_ITEMS) AS TOTAL
FROM   xxx

... qui équivaut à max(1,number_of_items).

Remplacez les trois 1s ci-dessus par une autre valeur, si nécessaire.

Cela fonctionne parce que number_of_items - 1 passe à zéro ou est négatif lorsque number_of_items est inférieur à 1. Et en général, x + abs(x) est toujours égal à zéro lorsque x <= 0, la première option decode correspond.

Nous en avons besoin car certains de nos clients (tiers) utilisent peut-être encore Oracle 8.0 et il faudrait plusieurs jours d'efforts pour déterminer si ou quand le dernier client sera enfin mis à niveau!

0
wardies