I need to add an extra column to my query results,
The column needs to be called percent,
If col1 == 0
then percent
should contain NIS
else percent
should contain ceil(col2 / col1 * 100)
So I believe the following should work:
IF(col1 = 0, 'NIS', ceil(col2 / col1 * 100)) as percent
But I run into an issue as col1 and col2 are also composite's.
COUNT(distinct i.id) as col1
COUNT(distinct q.id) as col2
So I get hit with
Unknown column 'col1' in 'field list'
I could get around that issue with
IF(COUNT(distinct i.id) = 0, 'NIS', ceil(COUNT(distinct q.id) / COUNT(distinct i.id) * 100)) as percent
But that just seems like a bunch of extra processing to me, surely there is a better way around that?
SELECT
`t`.*,
`r`.`name` AS region_name,
GROUP_CONCAT(DISTINCT p.ptype_id SEPARATOR "|") AS ptype_ids,
COUNT(DISTINCT q.id) AS quoted,
COUNT(DISTINCT i.id) AS intended,
COUNT(DISTINCT qa.id) AS awarded,
IF(
intended = 0,
`"NIS"`,
CEIL(quoted / intended * 100)
) AS percent
FROM
(`tradesmen` t)
LEFT JOIN `regions` r
ON `r`.`id` = `t`.`region_id`
LEFT JOIN `quotes` q
ON `t`.`id` = `q`.`tradesman_id`
LEFT JOIN `quote_intentions` i
ON `t`.`id` = `i`.`tradesman_id`
LEFT JOIN `quotes` qa
ON `q`.`tradesman_id` = `qa`.`tradesman_id`
AND qa.accepted = 1
LEFT JOIN `ptypes_tradesmen` p
ON `p`.`tradesman_id` = `t`.`id`
GROUP BY `t`.`id`
LIMIT 20
As mentioned in SELECT
Syntax:
It is not permissible to refer to a column alias in a
WHERE
clause, because the column value might not yet be determined when theWHERE
clause is executed. See Section C.5.5.4, “Problems with Column Aliases”.
Whilst the manual doesn't explicitly say so, the same reasoning applies to referring to a column alias within a select_expr
.
You could place your query in a subquery to an outer one that calculates percent
using the column aliases:
SELECT *, IF(intended, CEIL(quoted / intended * 100), NULL) AS percent FROM (
SELECT
`t`.*,
`r`.`name` AS region_name,
GROUP_CONCAT(DISTINCT p.ptype_id SEPARATOR "|") AS ptype_ids,
COUNT(DISTINCT q.id) AS quoted,
COUNT(DISTINCT i.id) AS intended,
COUNT(DISTINCT qa.id) AS awarded
FROM
(`tradesmen` t)
LEFT JOIN `regions` r
ON `r`.`id` = `t`.`region_id`
LEFT JOIN `quotes` q
ON `t`.`id` = `q`.`tradesman_id`
LEFT JOIN `quote_intentions` i
ON `t`.`id` = `i`.`tradesman_id`
LEFT JOIN `quotes` qa
ON `q`.`tradesman_id` = `qa`.`tradesman_id`
AND qa.accepted = 1
LEFT JOIN `ptypes_tradesmen` p
ON `p`.`tradesman_id` = `t`.`id`
GROUP BY `t`.`id`
LIMIT 20
) t
However, I don't think this is really worthwhile as I believe (am looking for a reference that I can cite, but nothing forthcoming yet) MySQL will only calculate each COUNT()
once and use the cached result in each reference.