组函数不支持mysql引用

时间:2014-04-17 21:24:55

标签: mysql group-by aggregate-functions

我有一个MySQL程序,它接受2个参数par_DateFrompar_DateTo

我收到了一个令人讨厌的错误。我非常确定重用别名TotalDaysOut来计算TotalIncome是罪魁祸首。我该如何优雅地解决这个问题?

错误1247: 引用TotalDaysOut不支持对组函数的引用

BEGIN
SELECT  t.LicencePlate
            ,f.Make
            ,f.Model
            ,f.Year

            ,COUNT(t.LicencePlate) AS TotalTrx          
            ,SUM(DATEDIFF(IF(checkedIn >par_DateTo, par_DateTo, checkedIn) ,IF(checkedOut <par_DateFrom, par_DateFrom, checkedOut))) AS TotalDaysOut
            ,SUM(t.Price* (SELECT TotalDaysOut)) AS TotalIncome
FROM        TRANSACTIONS    t
INNER JOIN FLEET            f
    ON t.LicencePlate = f.LicencePlate
WHERE t.CheckedOut < par_DateTo AND t.CheckedIn > par_DateFrom
GROUP BY t.LicencePlate
            ,f.Make
            ,f.Model
            ,f.Year;
END

2 个答案:

答案 0 :(得分:1)

你不能这样做。您无法在select的同一级别引用列别名,也不能在其定义位置引用列别名。我不确定确切的错误是什么,但(select TotalDaysOut)没有意义。

所以,用附加的乘法重复表达式:

     SUM(DATEDIFF(IF(checkedIn >par_DateTo, par_DateTo, checkedIn) ,IF(checkedOut <par_DateFrom, par_DateFrom, checkedOut))) AS TotalDaysOut,
     SUM(t.Price * DATEDIFF(IF(checkedIn >par_DateTo, par_DateTo, checkedIn) ,IF(checkedOut <par_DateFrom, par_DateFrom, checkedOut))) AS TotalIncome

答案 1 :(得分:1)

由于您的谓词已经验证表达式中引用的所有列都不为null:

checkedIn
par_DateTo
checkedOut
par_DateFrom

(WHERE子句中的谓词要求所有这些都是非NULL的),你可以简化表达式,引用每一列一次,而不是两次:

DATEDIFF(LEAST(t.checkedIn, par_DateTo),GREATEST(t.checkedOut, par_DateFrom))

并且(正如戈登已经建议的那样)只需重复那个需要结果的表达式。

当我们绝对必须引用查询中的别名时,MySQL中唯一真正的选择是使用内联视图,尽管这种方法对大型集合具有显着的性能影响。

SELECT v.LicencePlate
     , f.Make
     , f.Model
     , f.Year
     , COUNT(v.LicencePlate)  AS TotalTrx
     , SUM(v.DaysOut)         AS TotalDaysOut
     , SUM(v.DaysOut)*v.Price AS TotalIncome
  FROM ( SELECT t.LicencePlate
              , t.Price
              , DATEDIFF(
                  LEAST(t.checkedIn, par_DateTo),
                  GREATEST(t.checkedOut, par_DateFrom)
                ) AS DaysOut
          FROM TRANSACTIONS t
         WHERE t.CheckedOut < par_DateTo
           AND t.CheckedIn  > par_DateFrom
       ) v
  JOIN FLEET f
    ON f.LicencePlate = v.LicencePlate
 GROUP
    BY v.LicencePlate
     , f.Make
     , f.Model
     , f.Year

这不仅仅是简化和重复表达,而且性能较差,而且不那么优雅。