mysql复合如果来自复合值的列?

时间:2012-08-28 00:38:01

标签: mysql if-statement composite

我需要在查询结果中添加一个额外的列,

该列需要调用百分比, 如果col1 == 0percent应包含NIS其他percent应包含ceil(col2 / col1 * 100)

所以我相信以下内容应该有效:

IF(col1 = 0, 'NIS', ceil(col2 / col1 * 100)) as percent

但是我遇到了一个问题,因为col1和col2也是复合的。

COUNT(distinct i.id) as col1
COUNT(distinct q.id) as col2

所以我受到了

的打击
  

'字段列表'中的未知列'col1'

我可以解决这个问题 IF(COUNT(distinct i.id) = 0, 'NIS', ceil(COUNT(distinct q.id) / COUNT(distinct i.id) * 100)) as percent

但这对我来说似乎是一堆额外的处理,当然还有更好的方法吗?

完整查询

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 

1 个答案:

答案 0 :(得分:1)

SELECT Syntax中所述:

  

不允许在WHERE子句中引用列别名,因为在执行WHERE子句时可能尚未确定列值。请参阅Section C.5.5.4, “Problems with Column Aliases”

虽然手册没有明确说明,但同样的推理适用于在 select_expr 中引用列别名。

您可以将查询放在子查询中,使用列别名计算percent的外部查询:

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

但是,我认为这不值得,因为我相信(我正在寻找一个我可以引用的参考,但还没有即将发布)MySQL只会计算每个COUNT()一次,并在每个引用中使用缓存的结果。