2012-05-18 24 views
3

美好的一天,我的問題是關於優化SQL查詢。 下面的查詢速度慢:Sql將多個相似的子查詢壓縮到單個子查詢中

SELECT id, name, 
, (SELECT rank_time FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1)::date AS rank_time 
, (SELECT host_c FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS host_c 
, (SELECT index_pa FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pa 
, (SELECT links_pa FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pa 
, (SELECT index_pb FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pb 
, (SELECT links_pb FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pb 
FROM stage 
ORDER BY name; 

我認爲這主要是因爲從stage_rank反覆選擇,是否有可能使這種選擇完成一次,並獲得單發命中的所有領域?

此外,任何postgresql特定的功能可能會有所幫助嗎?

回答

9

PostgreSQL,您可以選擇整個記錄作爲一個字段,並在以後進行擴展:

SELECT id, name, (sr).* 
FROM (
     SELECT id, name, 
       (
       SELECT stage_rank 
       FROM stage_rank 
       WHERE stage = stage.id 
       ORDER BY 
         rank_time DESC 
       LIMIT 1 
       ) sr 
     FROM stage 
     ) q 
ORDER BY 
     name 

或重新編寫查詢:

SELECT DISTINCT ON (s.name, s.id, sr.rank_time, sr.id) 
     s.id, s.name, sr.* 
FROM stage s 
JOIN stage_rank sr 
ON  sr.stage = s.id 
ORDER BY 
     s.name, s.id, sr.rank_time DESC, sr.id DESC 

或重寫它的其他方式:

SELECT id, name, (sr).* 
FROM (
     SELECT s.id, s.name, sr, ROW_NUMBER() OVER (PARTITION BY s.id ORDER BY sr.rank_time DESC, sr.id DESC) rn 
     FROM stage 
     JOIN stage_rank sr 
     ON  sr.stage = s.id 
     ) q 
WHERE rn = 1 
ORDER BY 
     name 
+0

@Girafik:意思是「將字段sr'(這是一條記錄)擴展到構成字段中」。對不起,我忘了添加別名,請參閱帖子更新。 – Quassnoi

+0

請您提供PostgresQL文檔關於選擇記錄並擴展它的鏈接,非常感謝。 – Dfr

+1

@Dfr:http://www.postgresql.org/docs/9.1/static/rowtypes.html – Quassnoi