如何在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'