2011-05-22 3 views
48

Có cách nào để tái sử dụng trường được tính toán trong câu lệnh mysql hay không. Tôi nhận được lỗi "total_sale cột không xác định" cho:Tôi có thể sử dụng lại trường được tính toán trong truy vấn SELECT không?

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

hoặc tôi phải lặp lại phép tính, điều này sẽ làm cho câu lệnh SQL rất dài nếu tôi thêm tất cả các tính toán tôi cần.

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

tất nhiên tôi có thể thực hiện tất cả các tính toán trong chương trình php của mình.

Trả lời

61

Có, bạn có thể sử dụng lại các biến. Đây là cách bạn làm điều đó:

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

đọc thêm về nó ở đây: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html

[Chú ý: Hành vi này là không xác định. Theo tài liệu MySQL:]

Theo nguyên tắc chung, bạn không bao giờ được gán giá trị cho biến người dùng và đọc giá trị trong cùng một câu lệnh. Bạn có thể nhận được kết quả mong đợi, nhưng điều này không được đảm bảo.

+0

@OMG Ponies Mind elaborating? "@total_sale: =" là không đủ khai báo? – rzetterberg

+0

Đó là thiết lập biến, không khai báo nó. Khai báo có nghĩa là sử dụng câu lệnh 'SET' hoặc dạng xem bảng/nội tuyến có nguồn gốc. –

+1

"Bạn cũng có thể gán giá trị cho biến người dùng trong các câu lệnh khác ngoài SET. Trong trường hợp này, toán tử gán phải là: = và không = bởi vì toán tử sau được coi là toán tử so sánh = trong câu lệnh không SET:" – rzetterberg

5

Bạn có thể sử dụng một phụ chọn:

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

Bạn có thể sử dụng truy vấn con, như thế này:

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 

Edit:
cố định sản phẩm Descartes, giả định khóa chính là id.
Điều này tương đương với giải pháp của OMG Ponies sau khi tối ưu hóa, nhưng tôi nghĩ rằng sẽ khó đọc hơn nếu bạn cần thêm truy vấn phụ.

+1

Không có tiêu chí tham gia có nghĩa là sản phẩm cartesian ... –

+0

@OMG phải ... bằng cách nào đó tôi tưởng tượng điều này chỉ là một hàng ... – kiw

8

Chỉ cross-platform hỗ trợ phương tiện là bằng cách sử dụng một cái nhìn bảng/inline có nguồn gốc:

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

Sau đây dường như làm việc tốt trong thử nghiệm của tôi trên MySQL 5.5:

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

Thú vị. Tại sao nó hoạt động? –

+1

Tôi thích điều này. Cho đến nay khả năng đọc tốt nhất từ ​​tất cả các câu trả lời và không có cảnh báo về việc sử dụng nó trong tài liệu mysql. Tuy nhiên, nó không thể được sử dụng để tham chiếu các kết quả nhóm như những kết quả bạn nhận được với SUM hoặc COUNT. – David

+0

Vì câu trả lời được chấp nhận hiện tại không thể hoạt động mọi lúc, điều này có thể là câu trả lời được chấp nhận –

0

Tôi đã được thử nghiệm những điều sau đây và có vẻ như làm việc mọi lúc, có lẽ có một lý do cho điều này, có phải vì tôi đã định nghĩa trước biến @total_sales như là một giá trị không phải là chuỗi và không định nghĩa lại kiểu của nó trong câu lệnh chọn không ??

Nếu tôi làm như sau

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

tôi đã có một cái nhìn tại câu trả lời khác nhau ở đây và đã làm một vài thí nghiệm.

Cụ thể là tôi đang sử dụng MariaDB 10.1.

Đối với một điều "đơn giản" bạn có thể làm những gì Robert D đề xuất trong bình luận của ông:

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

Nếu bạn đang sử dụng một số loại chức năng tổng hợp với một bên tham gia bạn không thể sử dụng điều này, nhưng bạn có thể kết hợp phương pháp này với các bên tham gia phương pháp như sau (NB "thuế bán hàng" VAT = ... và NB trong lĩnh vực dữ liệu tài chính tiền tệ thường có 4 chữ số thập phân, tôi nghĩ rằng đó là di tích lịch sử ...)

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 

Tôi muốn sử dụng ở trên để tạo một View để liệt kê hóa đơn wi th subtotals của họ, thuế GTGT và tổng số ... nó bật ra rằng MariaDB (và gần như chắc chắn MySQL) không cho phép làm tổ trong mệnh đề FROM. Tuy nhiên, điều này có thể dễ dàng được giải quyết bằng cách thực hiện một số View đầu tiên liệt kê các số InvoiceNoSubtotal và sau đó thực hiện lần đầu tiên View tham chiếu đầu tiên. Hiệu suất-khôn ngoan Tôi không có ý tưởng ở tất cả về loại này sắp xếp đôi-View.