在mysql中重用计算列

时间:2009-04-22 11:58:39

标签: sql mysql

如何在MySQL中重用SQL中的计算列? 说:我的查询类似于: -

SELECT 
    CONVERT_TZ(
        if(timestamp_start > last_update, timestamp_start, last_update), 
        'GMT', 
        user.timezone
    ) as time_usr_tz
from 
    shecdule
    inner join user on shecdule.user_id = user.user_id
where 
    CONVERT_TZ(
        if(timestamp_start > last_update, timestamp_start, last_update), 
        'GMT', 
        user.timezone
    )
    < CURRENT_TIMESTAMP();

如果您看到查询,则重复“CONVERT_TZ .....”部分。

这只是一个示例查询。实际上,我必须多次使用该计算列。 所以,如果我在一个地方做出改变,我必须在很多地方改变。 查询的大小也变得可怕。

有没有办法避免这种重复?

更新 我在原始查询中已经有子查询,因此子查询不是一个更好的选择。是否有可能以任何其他方式?

1 个答案:

答案 0 :(得分:4)

SELECT  ctz
FROM    (
        SELECT  shecdule.*,
                CONVERT_TZ(
                if(timestamp_start > last_update, timestamp_start, last_update), 
                'GMT', 
                user.timezone
                ) AS ctz
        FROM    shecdule
        INNER JOIN
                user
        ON      user.user_id = s.user_id
        ) s
WHERE  ctz < CURRENT_TIMESTAMP()

请注意,此查询不会有效地使用timestamp_startlast_update上的索引。

请参阅我博客文章中的效果详情:

用两个词来说,你最好用这个:

SELECT  ctz
FROM    (
        SELECT  shecdule.*,
                CONVERT_TZ(
                if(timestamp_start > last_update, timestamp_start, last_update), 
                'GMT', 
                user.timezone
                ) AS ctz
        FROM    shecdule
        INNER JOIN
                user
        ON      user.user_id = s.user_id
        WHERE   timestamp_start < CURRENT_TIMESTAMP() + INTERVAL 14 HOUR
                OR last_update < CURRENT_TIMESTAMP() + INTERVAL 14 HOUR
        ) s
WHERE  ctz < CURRENT_TIMESTAMP()

此内部查询将使用索引对timestamp_startlast_update执行粗略过滤(区域转换不能将时间从+14:00偏移UTC以上)。

外部子查询将根据用户的时区精细过滤结果。

如果您不喜欢子查询,也可以使用:

SELECT  shecdule.*,
        CONVERT_TZ(
        if(timestamp_start > last_update, timestamp_start, last_update), 
        'GMT', 
        user.timezone
        ) AS ctz
FROM    shecdule
INNER JOIN
       user
ON      user.user_id = s.user_id
/* 
        WHERE   timestamp_start < CURRENT_TIMESTAMP() + INTERVAL 14 HOUR
                OR last_update < CURRENT_TIMESTAMP() + INTERVAL 14 HOUR
*/
HAVING  ctz < CURRENT_TIMESTAMP()