我有一个MySQL程序,它接受2个参数par_DateFrom
和par_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
答案 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
这不仅仅是简化和重复表达,而且性能较差,而且不那么优雅。