101 votes

Peut-on avoir une logique if-then-else en SQL ?

J'ai besoin de sélectionner des données dans un tableau en fonction d'une sorte de priorité, comme suit :

select product, price from table1 where project = 1

-- pseudo: if no price found, do this:
select product, price from table1 where customer = 2

-- pseudo: if still no price found, do this:
select product, price from table1 where company = 3

C'est-à-dire que si j'ai trouvé 3 produits dont les prix sont basés sur project = X Je ne veux pas sélectionner sur customer = Y . Je veux juste retourner les 3 rangées résultantes et en finir.

Comment faire ce genre de choses en SQL ? Utiliser une sorte d'instruction CASE pour les pseudo-si ? Faire une union ou autre chose d'intelligent ?

Edit : J'utilise MS SQL.

Merci !

109voto

voo Points 3505

Vous pouvez effectuer la requête sql suivante

IF ((SELECT COUNT(*) FROM table1 WHERE project = 1) > 0) 
    SELECT product, price FROM table1 WHERE project = 1
ELSE IF ((SELECT COUNT(*) FROM table1 WHERE project = 2) > 0) 
    SELECT product, price FROM table1 WHERE project = 2
ELSE IF ((SELECT COUNT(*) FROM table1 WHERE project = 3) > 0)
    SELECT product, price FROM table1 WHERE project = 3

31voto

kyle Points 2893

L'instruction CASE est ce qui se rapproche le plus d'une instruction IF en SQL, et elle est prise en charge par toutes les versions de SQL Server :

SELECT CASE <variable> 
           WHEN <value>      THEN <returnvalue> 
           WHEN <othervalue> THEN <returnthis> 
           ELSE <returndefaultcase> 
       END 
  FROM <table>

17voto

Andrey Gordeev Points 6348

Au lieu d'utiliser EXISTS y COUNT utilisez simplement @@ROWCOUNT :

select product, price from table1 where project = 1

IF @@ROWCOUNT = 0
BEGIN
    select product, price from table1 where customer = 2

    IF @@ROWCOUNT = 0
    select product, price from table1 where company = 3
END

2voto

Joachim Isaksson Points 85969

Avec le serveur SQL, vous pouvez simplement utiliser un CTE au lieu de la logique IF/THEN pour faciliter le mappage de vos requêtes existantes et modifier le nombre de requêtes concernées ;

WITH cte AS (
    SELECT product,price,1 a FROM table1 WHERE project=1   UNION ALL
    SELECT product,price,2 a FROM table1 WHERE customer=2  UNION ALL
    SELECT product,price,3 a FROM table1 WHERE company=3
)
SELECT TOP 1 WITH TIES product,price FROM cte ORDER BY a;

Un SQLfiddle pour tester avec .

Alternativement, vous pouvez tout combiner en un seul. SELECT afin de le simplifier pour l'optimiseur ;

SELECT TOP 1 WITH TIES product,price FROM table1 
WHERE project=1 OR customer=2 OR company=3
ORDER BY CASE WHEN project=1  THEN 1 
              WHEN customer=2 THEN 2
              WHEN company=3  THEN 3 END;

Un autre SQLfiddle .

1voto

TechDo Points 11224

Veuillez vérifier si cela vous aide :

select TOP 1
    product, 
    price 
from 
    table1 
where 
    (project=1 OR Customer=2 OR company=3) AND
    price IS NOT NULL
ORDER BY company

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X