2014-11-23 26 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)。我会从后面的索引开始,看看它是否能够提高性能,足以满足您的需求。