How to refactor select subqueries into joins?

故事扮演 提交于 2019-12-11 17:57:37

问题


I have an extremely ugly complex query that returns results for a race based on a series of groupings.

I have a table that contains registration information (name, etc), and a table that contains finish times. I need to get a place for each race, class, and division (they are sub groups of each other).

What I have working right now is this:

Select reg.name, r.fin_time
  ( select count(*)+1 from 
    ( Select temp_reg.id as regid, temp_reg.race_id as in_race, temp_res.division as in_div, 
         COALESCE(temp_res.fin_time, 9999999999) as finish_time 
      FROM results as temp_res Inner JOIN registration as temp_reg on temp_res.registration_id = temp_reg.id 
      WHERE COALESCE(temp_res.fin_time) > 0 
        AND temp_res.status ='Finished') as ahead_div 
    WHERE ahead_div.regid <> reg.registration_id 
      AND ahead_div.in_race = reg.race_id 
      AND ahead_div.in_div = r.division 
      AND ahead_div.finish_time < COALESCE(r.fin_time, 9999999999) ), '-') as fin_place_div,
... same for class and race...
FROM results as r inner join registration as reg on r.registration_id = reg.id 
WHERE r.status = 'Finished';

So I am collecting all the competitors that are finished, and counting them where they are in the same race and same div, and their finish time is < the finish time of this record.

I now have a situation where I need the calculated race finish place to be displayed as the class finish place.. so I need to either duplicate the race position subquery in an if statement (uglier and slow), or move the subqueries to the where clause so I can use them more than once.

How would I reformat this query from a "count() from subquery where" single value subquery in the select to a join?

Is there some what I can reuse the inner subquery? if in add the class to it, I could count from it for every place counting.

Cheers,


回答1:


I know this won't help your code look any cleaner, but performance wise if you simply re-use the same subquery it will likely be cached so there shouldn't be a performance hit (generally as long as it doesn't use session variables or is a correlated subquery).

See what EXPLAIN EXTENDED says and provided it doesn't come back with DEPENDENT SUBQUERY or UNREACHABLE SUBQUERY there shouldn't be a performance hit.

SELECT
   *
FROM
   (SELECT a FROM a) b INNER JOIN
   (SELECT a FROM a) c ON b.a = c.a

The query optimizer should cache the subquery so that it is not actually retrieved twice.



来源:https://stackoverflow.com/questions/16878631/how-to-refactor-select-subqueries-into-joins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!