2014-11-23 102 views
2

表格: 請在此處查看以查看錶格。 How to query counting specific wins of team and find the winner of the series如何在左連接中使用子查詢時優化查詢

問題:

  • 如何讓更多的查詢優化?
  • 如何減少查詢冗餘?
  • 如何使此查詢更快?

摘要

正如你可以在這個查詢例子這一部分是多次使用看看。

WHERE leagueid = 2096 
AND start_time >= 1415938900 
AND ((matches.radiant_team_id= 1848158 AND matches.dire_team_id= 15) 
OR (matches.radiant_team_id= 15 AND matches.dire_team_id= 1848158)) 

SELECT matches.radiant_team_id, 
     matches.dire_team_id, 
     matches.radiant_name, 
     matches.dire_name, 
     TA.Count AS teamA, 
     TB.Count AS teamB, 
     TA.Count + TB.Count AS total_matches, 
     SUM(TA.wins), 
     SUM(TB.wins), 
     (CASE 
      WHEN series_type = 0 THEN 1 
      WHEN series_type = 1 THEN 2 
      WHEN series_type = 2 THEN 3 
     END) AS wins_goal 
FROM matches 
LEFT JOIN 
    (SELECT radiant_team_id, 
      COUNT(id) AS COUNT, 
      CASE 
       WHEN matches.radiant_team_id = radiant_team_id && radiant_win = 1 THEN 1 
      END AS wins 
    FROM matches 
    WHERE leagueid = 2096 
    AND start_time >= 1415938900 
    AND ((matches.radiant_team_id= 1848158 
      AND matches.dire_team_id= 15) 
      OR (matches.radiant_team_id= 15 
       AND matches.dire_team_id= 1848158)) 
    GROUP BY radiant_team_id) AS TA ON TA.radiant_team_id = matches.radiant_team_id 
LEFT JOIN 
    (SELECT dire_team_id, 
      COUNT(id) AS COUNT, 
      CASE 
       WHEN matches.dire_team_id = dire_team_id && radiant_win = 0 THEN 1 
      END AS wins 
    FROM matches 
    WHERE leagueid = 2096 
    AND start_time >= 1415938900 
    AND ((matches.radiant_team_id= 1848158 
      AND matches.dire_team_id= 15) 
      OR (matches.radiant_team_id= 15 
       AND matches.dire_team_id= 1848158)) 
    GROUP BY dire_team_id) AS TB ON TB.dire_team_id = matches.dire_team_id 
WHERE leagueid = 2096 
    AND start_time >= 1415938900 
    AND ((matches.radiant_team_id= 1848158 
     AND matches.dire_team_id= 15) 
     OR (matches.radiant_team_id= 15 
      AND matches.dire_team_id= 1848158)) 
GROUP BY series_id 

計劃匹配

ID| leagueid| team_a_id| team_b_id| starttime 
1|  2096| 1848158|  15| 1415938900 

回答

1

我相信這可以在沒有子查詢的情況下完成。

我提出了以下的匹配表

enter image description here

,並用於下面的查詢分組的結果,每系列

SELECT 
     matches.leagueid, 
     matches.series_id, 
     matches.series_type, 
     COUNT(id) as matches, 
     IF(radiant_team_id=1848158,radiant_name, dire_name) AS teamA, 
     IF(radiant_team_id=1848158,dire_name, radiant_name) AS teamB, 
     SUM(CASE 
      WHEN radiant_team_id=1848158 AND radiant_win=1 THEN 1 
      WHEN dire_team_id=1848158 AND radiant_win=0 THEN 1 
      ELSE 0 END) AS teamAwin, 
     SUM(CASE 
      WHEN radiant_team_id=15 AND radiant_win=1 THEN 1 
      WHEN dire_team_id=15 AND radiant_win=0 THEN 1 
      ELSE 0 END) AS teamBwin 

FROM `matches` 
WHERE leagueid = 2096 
    AND start_time >= 1415938900 
AND dire_team_id IN (15, 1848158) 
AND radiant_team_id IN (15, 1848158) 
group by leagueid,series_id,series_type,teamA,teamB 

一個線,其產生以下結果

enter image description here

請注意,將一個系列的結果進行分組時,並不存在輻射團隊或可怕團隊等。在同一系列賽中,角色和角色可能會被切換多次,所以我只將隊名稱爲teamA和teamB。

現在,看看你之前的問題,我發現你需要根據系列類型和每支球隊的勝利來確定系列賽冠軍。這將需要包裝以前的查詢並將其用作子查詢,如

SELECT matchresults.*, 
     CASE series_type 
     WHEN 0 then IF(teamAwin>=1, teamA,teamB) 
     WHEN 1 then IF(teamAwin>=2, teamA,teamB) 
     ELSE IF(teamAwin>=3, teamA,teamB) 
     END as winner 

from (THE_MAIN_QUERY) as matchresults 
+0

WOOOOOOOOOOH。而已。你是最好的。非常感謝你 。這個問題是1周老〜〜/〜然後在最後。你解決了它:D非常感謝! – ronscript 2014-11-24 00:55:07

+0

我有問題。如果我想使radiant_team_id和dire_team_id動態,該怎麼辦?例如我不想過濾出使用團隊ID。 – ronscript 2014-11-24 01:16:29

+0

這取決於。一系列確定了一個獨特的團隊對?或者它確實解決了可以應用於多個團隊對的階段?除此之外,您需要考慮模型層面有多少邏輯,以及可以使用業務邏輯來管理多少邏輯。 – amenadiel 2014-11-24 01:23:10

1

可能有更有效的方式得到你想要的結果。但是,爲了使這個查詢更有效率,您可以添加索引。這是多次where條款:

WHERE leagueid = 2096 AND 
     start_time >= 1415938900 AND 
     ((matches.radiant_team_id= 1848158 AND matches.dire_team_id= 15) OR 
     (matches.radiant_team_id= 15 AND matches.dire_team_id= 1848158)) 

條件與or是很難優化。以下指數將有所幫助:matches(leagueid, start_time)。覆蓋指數(至少爲where條件)爲matches(leagueid, start_time, radiant_team_id, dire_team_id)。我會從後面的索引開始,看看它是否能夠提高性能,足以滿足您的需求。