2009-04-22 11 views
1

MySQLの計算カラムをSQLで再利用する方法はありますか? セイ:私のクエリのようなものです: - あなたは「CONVERT_TZ .....」の部分が繰り返されたクエリが表示される場合は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(); 

これはサンプルクエリです。実際には、その計算列を何回か使用する必要があります。 私は1か所で変更を加えると、多くの場所で変更する必要があります。 また、クエリのサイズも怖くなります。

このような重複を避ける方法はありますか?

更新 私はすでに元のクエリでサブクエリを使用しているため、サブクエリは適切なオプションではありません。他の方法でも可能ですか?

答えて

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_startかつ効率的にlast_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()