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

Est-il possible de réutiliser un champ calculé dans une instruction mysql. J’ai l’erreur “colonne inconnue 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 entraînerait une très longue instruction SQL si j’ajoutais tous les calculs nécessaires.

 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.

Oui, vous pouvez réutiliser les 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 

En savoir plus à ce sujet ici: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html

[Remarque: Ce comportement n’est pas défini. Selon les documents MySQL:]

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

Ce qui suit semble bien fonctionner dans 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 

Seul un moyen supporté par plusieurs plates-formes est d’utiliser une vue table / inline dérivée:

 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 

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; 

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 de OMG Ponies après optimisation, mais je pense que cela deviendra plus difficile à lire si vous avez besoin de plus de sous-requêtes.

J’ai testé ce qui suit et il semble fonctionner tout le temps, peut-être y a-t-il une raison à cela, est-ce parce que j’ai prédéfini la variable @total_sales comme étant une valeur et non une chaîne, et que 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 

J’ai jeté un coup d’œil aux différentes réponses ici et j’ai fait quelques expériences.

Plus précisément, j’utilise MariaDB 10.1.

Pour une chose “simple”, vous pouvez faire ce que Robert D a suggéré dans son commentaire:

 SELECT Price_Per_SqFt, (Price_Per_SqFt/2) AS col1, (SELECT col1 + 1) AS col2 FROM Items 

Si vous utilisez une fonction d’agrégat avec une jointure interne, vous ne pouvez pas l’utiliser, mais vous pouvez combiner cette approche avec l’approche de jointure interne comme suit (NB TVA = “taxe de vente” … et NB dans la devise de données financières les champs ont généralement 4 décimales, je pense que c’est historique …)

 SELECT invoices.invoiceNo, invoices.clientID, invoices.Date, invoices.Paid, invoicesWithSubtotal.Subtotal, ROUND( CAST( Subtotal * invoices.VATRate AS DECIMAL( 10, 4 )), 2 ) AS VAT, (SELECT VAT + Subtotal) AS Total FROM invoices INNER JOIN ( SELECT Sum( invoiceitems.Charge ) AS Subtotal, invoices.InvoiceNo FROM invoices INNER JOIN invoiceitems ON invoices.InvoiceNo = invoiceitems.InvoiceNo GROUP BY invoices.InvoiceNo ) invoicesWithSubtotal ON invoices.InvoiceNo = invoicesWithSubtotal.InvoiceNo 

Je voulais utiliser ce qui précède pour créer une View permettant de répertorier les factures avec leurs sous-totaux, leur TVA et leurs totaux… Il s’est avéré que MariaDB (et presque certainement MySQL) n’autorise pas l’imbrication dans la clause FROM . Cependant, cela est facilement résolu en créant une première View qui répertorie les InvoiceNo et les Subtotal InvoiceNo , puis en créant une seconde View qui fait référence au premier. Sur le plan de la performance, je n’ai aucune idée de ce type d’arrangement double- View .