如何在SQL查询中排除重复的表达式?列别名似乎不是问题所在

如何在SQL查询中排除重复的表达式?列别名似乎不是问题所在,sql,select,expression,column-alias,Sql,Select,Expression,Column Alias,我有一个类似这样的查询: 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

我有一个类似这样的查询:

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'
这是我学到的,引用MySQL手册:

标准SQL不允许引用 WHERE子句中的列别名。这 实施限制是因为 在计算WHERE子句时 列值可能还没有确定 下定决心

因此,这种方法似乎是行不通的


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

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

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'

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

两个问题:1一般来说:我是否担心这会导致在内部查询中选择cs_calldata中的所有行,然后使用外部查询筛选它们,这似乎效率低下,或者这是大多数数据库都足够聪明,可以为其创建更好的查询计划的东西吗?2具体来说,MySQL有那么聪明吗我不指望MySQL将来自内部和外部查询的行限制结合起来,但解释将有助于确认这一点。至少customerCode的条件在内部查询中,因此限制了内部查询中的函数处理的行数。1通常不需要担心。许多RDBMS上的查询优化器将折叠/合并所有内容。在应用查询的外部部分之前,使用内联视图不会实现。我不知道。
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'
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'