2011-05-22 32 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,这引用了第一个。在性能方面,我完全不知道这种双排扣方式。

相关问题