2011-05-22 33 views
48

有沒有辦法在mysql語句中重用計算的字段。我得到的錯誤「未知列total_sale」:我可以在SELECT查詢中重複使用計算的字段嗎?

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程序中做所有的計算。

回答

61

是的,你可以重用變量。這是你如何做到這一點:

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文檔:]

作爲一般規則,您不應該爲用戶變量賦值並讀取同一語句中的值。您可能會得到您期望的結果,但這並不能保證。

+0

@OMG小馬心靈闡述? 「@total_sale:=」是不是足夠的聲明? – rzetterberg 2011-05-22 01:30:10

+0

這是設置變量,而不是聲明它。聲明意味着使用'SET'語句或派生表/內聯視圖。 「 – 2011-05-22 01:31:14

+1

」您也可以在SET以外的語句中爲用戶變量賦值,在這種情況下,賦值運算符必須爲:=和not =,因爲後者在非SET語句中被視爲比較運算符=「 – rzetterberg 2011-05-22 01:32:46

5

您可以使用子選擇:

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; 
3

您可以使用子查詢,像這樣:

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的解決方案,但如果您需要更多的子查詢,我認爲它會變得更難閱讀。

+1

沒有加入標準意味着笛卡爾產品... – 2011-05-22 01:29:47

+0

@OMG右...不知何故,我想像這只是關於只有一行... – kiw 2011-05-22 01:33:56

8

只有跨平臺支持的手段是通過使用派生表/內嵌視圖:

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 
35

下,似乎在我的測試在MySQL 5.5很好地工作:

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

有趣。它爲什麼有效? – 2015-09-08 09:15:37

+1

我喜歡這個。到目前爲止,所有答案都是最好的可讀性,並且沒有關於在mysql文檔中使用它的警告。但是,它不能用於引用組結果,例如您使用SUM或COUNT獲得的結果。 – David 2015-09-16 16:51:27

+0

由於目前接受的答案不可能每次都工作,這應該是被接受的答案 – 2016-06-07 08:24:48

0

我一直測試下面,它似乎一直工作,也許這是有原因的,是因爲我已經預定義變量@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

我看了一下這裏的各種答案,並做了一些實驗。

具體來說,我使用的是MariaDB 10.1。

對於一個「簡單」的事情你可以做什麼羅伯特·d在他的評論中建議:

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

如果您正在使用某種形式的聚合函數與內部連接則不能使用,但你可這種做法與內部相結合的方式加入如下(以財務數據貨幣字段NB增值稅=「銷售稅」 ......和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來列出發票wi他們的小計,增值稅和總計......事實證明,MariaDB(並且幾乎可以肯定是MySQL)不允許嵌套在FROM條款中。然而,通過首先製作第一個View,其中列出了InvoiceNoSubtotal,然後再製作第二個View,這引用了第一個。在性能方面,我完全不知道這種雙排扣方式。

相關問題