web-dev-qa-db-fra.com

Puis-je réutiliser un champ calculé dans une requête SELECT?

Existe-t-il un moyen de réutiliser un champ calculé dans une instruction mysql? J'obtiens l'erreur "unknown column total_sale" pour:

SELECT 
    s.f1 + s.f2 as total_sale, 
    s.f1 / total_sale as f1_percent
FROM sales s

ou dois-je répéter le calcul, ce qui donnerait une très longue instruction SQL si j'y ajoutais tous les calculs dont j'avais besoin.

SELECT 
    s.f1 + s.f2 as total_sale, 
    s.f1 / (s.f1 + s.f2) as f1_percent
FROM sales s

bien sûr, je peux faire tous les calculs dans mon programme php.

58
sdfor

Oui, vous pouvez réutiliser des variables. Voici comment vous le faites: 

SELECT 
    @total_sale := s.f1 + s.f2 as total_sale, 
    s.f1 / @total_sale as f1_percent
FROM sales s

Plus d'informations à ce sujet ici: http://dev.mysql.com/doc/refman/5.0/fr/user-variables.html

[Remarque: ce comportement n'est pas défini. Selon la documentation MySQL:]

En règle générale, vous ne devez jamais attribuer une valeur à une variable utilisateur et lire la valeur dans la même instruction. Vous pouvez obtenir les résultats escomptés, mais cela n’est pas garanti.

70
rzetterberg

Ce qui suit semble bien fonctionner lors de mes tests sur MySQL 5.5:

SELECT 
    s.f1 + s.f2 as total_sale, 
    s.f1 / (SELECT total_sale) as f1_percent
FROM sales s
47
Robert D

Seuls les moyens pris en charge sur plusieurs plates-formes utilisent une vue sous forme de tableau/en ligne:

SELECT x.total_sale,
       x.f1 / x.total_sale as f1_percent
  FROM (SELECT s.f1,
               s.f1 + s.f2 as total_sale, 
          FROM sales s) x
12
OMG Ponies

Vous pouvez utiliser une sous-sélection:

select tbl1.total_sale,
       tbl1.f1/tbl1.total_sale as f1_percent 
  from (select s.f1+s.f2 AS total_sale, 
               s.f1 
          from sales s) as tbl1;
6
AJ.

Vous pouvez utiliser des sous-requêtes, comme ceci:

SELECT 
    h.total_sale, 
    s.f1 / h.total_sale AS f1_percent
FROM sales s,
    (SELECT id, f1 + f2 AS total_sale FROM sales) h
WHERE
    s.id = h.id

Modifier:
produit cartésien fixe, en supposant que la clé primaire est id.
Cela devrait être équivalent à la solution d'OMG Ponies après l'optimisation, mais je pense qu'il sera plus difficile à lire si vous avez besoin de plus de sous-requêtes.

4
kiw

J'ai testé ce qui suit et il semble fonctionner tout le temps. Peut-être y a-t-il une raison à cela, car j'ai prédéfini la variable @total_sales comme étant une valeur et non une chaîne, et je n'ai pas redéfini son type lors de la sélection déclaration ??

Si je fais ce qui suit

    set @total_sales = 0;

    SELECT 
       @total_sale := s.f1 + s.f2 as total_sale, 
      s.f1 / @total_sale as f1_percent
   FROM sales s
0
Lawrence Edel