3

所以,我有一个看起来像这样的查询:

SELECT id, 
    DATE_FORMAT(CONVERT_TZ(callTime,'+0:00','-7:00'),'%b %d %Y') as callDate, 
    DATE_FORMAT(CONVERT_TZ(callTime,'+0:00','-7:00'),'%H:%i') as callTimeOfDay, 
    SEC_TO_TIME(callLength) as callLength
FROM cs_calldata WHERE 
    customerCode='999999-abc-blahblahblah' AND 
    CONVERT_TZ(callTime,'+0:00','-7:00') >= '2010-04-25' AND
    CONVERT_TZ(callTime,'+0:00','-7:00') <= '2010-05-25'

如果您像我一样,您可能会开始认为,如果我不要求它分别计算CONVERT_TZ(callTime,'+0:00','-7:00')四次,它可能会提高该查询的可读性和性能。

因此,我尝试为该表达式创建一个列别名,并用该别名替换进一步出现的情况:

SELECT id, 
    CONVERT_TZ(callTime,'+0:00','-7:00') as callTimeZoned,
    DATE_FORMAT(callTimeZoned,'%b %d %Y') as callDate, 
    DATE_FORMAT(callTimeZoned,'%H:%i') as callTimeOfDay, 
    SEC_TO_TIME(callLength) as callLength
FROM cs_calldata WHERE 
    customerCode='5999999-abc-blahblahblah' AND 
    callTimeZoned >= '2010-04-25' AND
    callTimeZoned <= '2010-05-25'

这是我学习的时候,引用 MySQL 手册:

标准 SQL 不允许在 WHERE 子句中引用列别名。施加此限制是因为在评估 WHERE 子句时,可能尚未确定列值。

所以,这种方法似乎已经死了。

有人用这样的重复表达式编写查询应该如何处理它?

4

2 回答 2

5

您可以在派生表中定义别名,然后在外部查询中引用它们:

SELECT callTimeZoned, callLength,
    DATE_FORMAT(callTimeZoned,'%b %d %Y') as callDate, 
    DATE_FORMAT(callTimeZoned,'%H:%i') as callTimeOfDay 
FROM (
    SELECT
        CONVERT_TZ(callTime,'+0:00','-7:00') as callTimeZoned,
        SEC_TO_TIME(callLength) as callLength
    FROM cs_calldata
    WHERE customerCode='5999999-abc-blahblahblah'
) AS d
WHERE 
    callTimeZoned BETWEEN '2010-04-25' AND '2010-05-25'
于 2010-05-26T02:26:14.437 回答
1
SELECT id, 
    CONVERT_TZ(callTime,'+0:00','-7:00') as callTimeZoned,
    DATE_FORMAT(callTimeZoned,'%b %d %Y') as callDate, 
    DATE_FORMAT(callTimeZoned,'%H:%i') as callTimeOfDay, 
    SEC_TO_TIME(callLength) as callLength
FROM cs_calldata WHERE 
    customerCode='5999999-abc-blahblahblah' having
    callTimeZoned >= '2010-04-25' AND
    callTimeZoned <= '2010-05-25'

(注意从第三行到最后一行的切换。ANDhaving

于 2012-04-12T11:58:34.193 回答