2013-07-30 4 views
0

J'essaie d'utiliser l'instruction CASE dans Mysql, et bien que MySQL ne se plaint pas de ma requête, elle ne parvient pas à fournir les bons résultats.Pourquoi MySQL Switch-Case ne sélectionne pas les bonnes valeurs?

Ce que j'essaie de faire est l'équivalent de:

if value < 20 then 1 
elseif value < 30 then 2 
elseif value < 40 then 3 
. 
. 
. 
else value < 90 then 45 

ce qui est ma déclaration MySQL:

SELECT 
    UM.DA, 
    UM.PA, 
    IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) AS "PS", 
CASE 
    WHEN "PS" < 20 THEN 1 
    WHEN "PS" < 30 THEN 2 
    WHEN "PS" < 40 THEN 3 
    WHEN "PS" < 50 THEN 5 
    WHEN "PS" < 60 THEN 8 
    WHEN "PS" < 70 THEN 12 
    WHEN "PS" < 80 THEN 20 
    WHEN "PS" < 90 THEN 30 
    WHEN "PS" >= 90 THEN 45 
END AS "Points", 
FROM 
    Table1 UM 

et ceci est mon jeu de résultats:

+-------+-------+--------+--------+ 
| UM.DA | UM.PA | PS | Points | 
+-------+-------+--------+--------+ 
| 19.21 | 18.39 | 18.39 | 1 | 
+-------+-------+--------+--------+ 
| 24.80 | 34.91 | 34.91 | 1 | 
+-------+-------+--------+--------+ 
| 29.72 | 35.89 | 35.89 | 1 | 
+-------+-------+--------+--------+ 

Voici à quoi devrait ressembler mon résultat:

+-------+-------+--------+--------+ 
| UM.DA | UM.PA | PS | Points | 
+-------+-------+--------+--------+ 
| 19.21 | 18.39 | 18.39 | 1 | 
+-------+-------+--------+--------+ 
| 24.80 | 34.91 | 34.91 | 3 | 
+-------+-------+--------+--------+ 
| 29.72 | 35.89 | 35.89 | 3 | 
+-------+-------+--------+--------+ 

Alors quelle est la bonne façon d'utiliser « CASE » dans les requêtes MySQL (ceci est une requête, et non une procédure stockée)

En outre, en termes de performance est-il préférable de mettre cette logique dans le SQL requête, ou devrais-je filtrer les résultats dans le langage de programmation de mon choix?

Merci!

+0

Pourquoi appliquez-vous le format PS entre guillemets dans l'instruction Case-When? C'est un nom de colonne. –

+0

Parce que MySQL se plaint si je ne sais pas – ILikeTacos

Répondre

2

Essayez ceci:

SELECT DA, PA, PS, 
     CASE 
      WHEN PS < 20 THEN 1 
      WHEN PS < 30 THEN 2 
      WHEN PS < 40 THEN 3 
      WHEN PS < 50 THEN 5 
      WHEN PS < 60 THEN 8 
      WHEN PS < 70 THEN 12 
      WHEN PS < 80 THEN 20 
      WHEN PS < 90 THEN 30 
      ELSE 45 
     END AS "Points" 
FROM (SELECT DA, PA, 
      IF((DA - PA) > 25, DA, PA) AS PS 
     FROM Table1 UM) temp 

Il déplace le calcul PS dans une sous-requête, il peut donc être référencée dans l'expression CASE sans répéter le calcul. Et PS doit être un nom, pas une chaîne.

+0

Ma version de MySQL se plaint si je ne supprime pas les guillemets, il renvoie "colonne inconnue PS Dans la liste des champs " – ILikeTacos

+0

C'est parce que vous ne pouvez pas faire référence à un alias dans la même liste SELECT que celle définie. C'est pourquoi je l'ai déplacé dans une sous-requête dans ma réponse. – Barmar

+0

vous devriez utiliser des guillemets ici 'UM.DA' ou il sera considéré comme table et colonne –

0

"PS" est simplement une chaîne. Ce n'est PAS l'alias que vous avez créé, donc vous comparez une chaîne à un entier, et mysql convertira automatiquement cette chaîne "PS" en un entier, ce qui en fera 0, donc TOUTES les observations correspondent. Vous voulez

CASE 
    WHEN PS < 20 THEN 1 
     ^^---note lack of quotes 
+0

Vous ne pouvez pas faire référence à des alias dans la même sélection – Bohemian

+0

Oui, cela aussi ... –

0

Je ne pense pas que vous pouvez utiliser un alias pour une colonne dans une requête, à moins que c'est la clause ORDER BY. En conséquence (en particulier en raison d'alias par des marques de discours pas des backticks) vous faites une comparaison de chaîne. Modifier la requête:

SELECT 
    UM.DA, 
    UM.PA, 
    IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) AS "PS", 
CASE 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 20 THEN 1 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 30 THEN 2 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 40 THEN 3 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 50 THEN 5 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 60 THEN 8 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 70 THEN 12 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 80 THEN 20 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) < 90 THEN 30 
    WHEN IF((UM.DA - UM.PA) > 25, UM.DA, UM.PA) >= 90 THEN 45 
END AS "Points", 
FROM 
    Table1 UM 
Questions connexes