尝试在where子句中使用别名列名时出错

时间:2015-05-15 08:52:47

标签: mysql

我的SQL查询有问题。我想按债务金额选择记录。金额按两个表的关系计算。

这很好用:

SELECT `i`.*, 
(i.amount_netto + (i.amount_netto * i.vat / 100)) - (SUM(p.amount_netto)) AS `debt`,
`e`.`name` AS `user_name`,
`e`.`surname` AS `user_surname`,
`c`.`name` AS `contractor_name`
FROM `invoices` AS `i` 
INNER JOIN `payments` AS `p` ON i.id = p.invoice_id 
INNER JOIN `employees` AS `e` ON i.employee_id = e.id 
INNER JOIN `contractors` AS `c` ON i.contractor_id = c.id 
GROUP BY `i`.`id` 
ORDER BY `debt` ASC

但是当我按debt添加WHERE子句时,我收到错误:

Unknown column 'debt' in 'where clause'

查询如下所示:

SELECT `i`.*, 
(i.amount_netto + (i.amount_netto * i.vat / 100)) - (SUM(p.amount_netto)) AS `debt`, 
`e`.`name` AS `user_name`,
`e`.`surname` AS `user_surname`,
`c`.`name` AS `contractor_name`
FROM `invoices` AS `i` 
INNER JOIN `payments` AS `p` ON i.id = p.invoice_id 
INNER JOIN `employees` AS `e` ON i.employee_id = e.id 
INNER JOIN `contractors` AS `c` ON i.contractor_id = c.id 
WHERE `debt` > 1 
GROUP BY `i`.`id` 
ORDER BY `debt` ASC

为什么我无法在WHERE子句中访问debt,但我可以在ORDER子句中访问?

2 个答案:

答案 0 :(得分:3)

debt不是列,而是别名。在执行查询之后才会解析列(表达式)别名,因此它们不能在WHERE子句中使用。

例如,此查询不合法:

select foo + 3 as bar
from baz
where bar = 39

而你必须重写WHERE子句中的整个表达式:

select foo + 3 as bar
from baz
where foo + 3 = 39

此外,由于debt实际上是基于聚合,因此无法在WHERE子句中对其进行过滤。您必须使用HAVING来评估聚合后的谓词 。因此,您的查询应该是:

SELECT ...
FROM ...
GROUP BY ...
HAVING (i.amount_netto + (i.amount_netto * i.vat / 100)) - (SUM(p.amount_netto)) > 1
ORDER BY ...

请注意drafting and prompting the user to send a message,因此您也可以这样做:

SELECT ...
FROM ...
GROUP BY ...
HAVING debt > 1
ORDER BY ...

答案 1 :(得分:1)

SQL通常不允许您在WHERE,GROUP BY或HAVING子句中引用列别名。 MySQL确实支持在GROUP BY和HAVING中引用列别名

尝试将您的查询位置更改为

WHERE (i.amount_netto + (i.amount_netto * i.vat / 100)) - (SUM(p.amount_netto)) > 1 GROUP BY i.id ORDER BY debt ASC

另一种选择,你可以使用子查询

SELECT * from (`i`.*, (i.amount_netto + (i.amount_netto * i.vat / 100)) - (SUM(p.amount_netto)) AS `debt`, `e`.`name` AS `user_name`, `e`.`surname` AS `user_surname`, `c`.`name` AS `contractor_name` FROM `invoices` AS `i` INNER JOIN `payments` AS `p` ON i.id = p.invoice_id INNER JOIN `employees` AS `e` ON i.employee_id = e.id INNER JOIN `contractors` AS `c` ON i.contractor_id = c.id  GROUP BY `i`.`id`) as newTable
WHERE `debt` > 1 ORDER BY `debt` ASC