How can I reuse a computed column in SQL in MySQL? Say: my query is something like: -
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();
If you see the query the "CONVERT_TZ....." part is repeated.
This is only a sample query. Actually, I have to use that computed column several times. So if I make change in one place, I have to change in many places. And the size of the query becomes scary, too.
Is there any way to avoid such duplication?
UPDATE I already have sub-query in my original query, so sub-query is not a preferable option. Is it possible in any other way?
-
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()
Note that this query doesn't use the indexes on
timestamp_start
andlast_update
efficiently.See the performance details in the article in my blog:
In two words, you better use this:
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()
This inner query will perform coarse filtering on
timestamp_start
andlast_update
using indexes (no zone conversion can offset the time more than+14:00
hours fromUTC
).The outer subquery will then fine filter the results based on user's time zone.
If you don't like subqueries, you may also use:
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()
0 comments:
Post a Comment