2009-04-22 76 views
1

如何在MySQL中重用SQL中的計算列? 說:我的查詢是這樣的: -在mysql中重用計算列

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 .....」部分重複查詢。

這只是一個示例查詢。實際上,我必須多次使用該計算列。 所以,如果我在一個地方做出改變,我必須在許多地方改變。 查詢的大小也變得可怕。

有什麼辦法可以避免這種重複?

UPDATE 我已經在我原來的查詢中有子查詢,所以子查詢不是一個可取的選項。有沒有可能以其他方式?

回答

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(無區域轉換可以抵消超過的時間小時,從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()