web-dev-qa-db-ja.com

SELECTクエリで計算フィールドを再利用できますか?

Mysqlステートメント内で計算フィールドを再利用する方法はありますか。エラー「unknown column total_sale」が表示されます:

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

または、計算を繰り返す必要がありますか。必要な計算をすべて追加すると、SQLステートメントが非常に長くなります。

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

もちろん、私のphpプログラムですべての計算を行うことができます。

62
sdfor

はい、変数を再利用できます。これがあなたのやり方です:

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

詳細はこちらをご覧ください: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html

[注:この動作は未定義です。 MySQLのドキュメントによると:]

一般的なルールとして、ユーザー変数に値を割り当てたり、同じステートメント内で値を読み取ったりしないでください。期待どおりの結果が得られる可能性がありますが、これは保証されません。

76
rzetterberg

以下は、MySQL 5.5でのテストでうまく機能しているようです。

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

クロスプラットフォームでサポートされる手段は、派生テーブル/インラインビューを使用することのみです。

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
13
OMG Ponies

サブセレクトを使用できます:

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.

次のようなサブクエリを使用できます。

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

編集:
主キーがidであると仮定したデカルト積を修正しました。
これは最適化後のOMG Poniesのソリューションと同等になりますが、サブクエリがさらに必要になると読みにくくなると思います。

4
kiw

ここでさまざまな答えを見て、いくつかの実験を行いました。

具体的には、MariaDB 10.1を使用しています。

「単純な」ことについては、Robert Dがコメントで提案したことを実行できます。

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

内部結合で何らかの集約関数を使用している場合、これは使用できませんが、次のようにこのアプローチと内部結合アプローチを組み合わせることができます(NB VAT = "sales tax" ... and NB通貨フィールドは通常、小数点以下4桁です。これは歴史的なものだと思います...)

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

上記を使用してViewを作成し、小計、VAT、および合計を含む請求書を一覧表示したかったのですが、MariaDB(およびほぼ確実にMySQL)がFROM句。ただし、これはViewInvoiceNoをリストする最初のSubtotalを作成し、次に最初のViewを参照することで簡単に解決できます。パフォーマンスに関しては、この種のdouble -View配置についてはまったくわかりません。

0
mike rodent

私は以下をテストしてきましたが、常に動作しているようです、おそらくこれには理由があります、変数@total_salesを文字列ではなく値として事前定義しており、選択中にそのタイプを再定義していないためステートメント??

私が次のことをすれば

    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