代码之家  ›  专栏  ›  技术社区  ›  JimBelushi2

在“where”子句中组合两个子查询的好方法

  •  2
  • JimBelushi2  · 技术社区  · 7 年前

    我有这个模式:

    CLUB(Name, Address, City)
    TEAM(TeamName, club)
    PLAYER(Badge, teamName)
    MATCH(matchNumber, player1, player2, club, winner)
    

    我需要进行以下查询:

    对于每个俱乐部,找出该俱乐部中获胜的球员的数量 至少两场比赛。

    我写的是:

    SELECT teamName
    From TEAM t join Match m1 on t.club=m1.club
    WHERE Q2 >= ALL Q1
    

    Q1:

    SELECT Count (Distinct winner)
    FROM MATCH
    WHERE match m join player p on m. winner=player.badge
    GROUP BY teamName
    

    Q2:

    SELECT Count (distinct winner)
    FROM match m2
    WHERE m2.club=m1.club
    

    我不知道这是否正确,但是我听说在面对两个问题时使用这个表单并不是最好的。为什么?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Aaron Dietz    7 年前

    试试这样的:

    SELECT club, COUNT(*) as PlayerCount
    FROM (SELECT club, winner
          FROM match
          GROUP BY club, winner
          HAVING COUNT(*) > 1) a
    GROUP BY club
    

    内部查询应将结果限制为有两个或更多赢球的俱乐部/球员组合,外部查询将计算每个俱乐部的这些球员数。

    我不知道这是不是正确的,但是我听说使用这种形式,我面对两个计数不是最好的。为什么?

    如果需要,比较两个计数子查询是可以的,但是一个好的经验法则是尽可能少地命中每个表。使用多个子查询将导致多次命中每个表,并且 通常 导致更长的执行时间。

        2
  •  1
  •   Eric    7 年前

    尝试此查询

    SELECT t.club, COUNT(*)
    FROM TEAM t
    JOIN PLAYER p ON p.teamName = t.TeamName
    JOIN (
        -- Won at least 2 matches.
        SELECT club, winner, COUNT(*) AS TheCount
        FROM MATCH
        GROUP BY club, winner
        HAVING COUNT(*) > 1
    ) w ON w.winner = p.badge AND w.club = t.club
    GROUP BY t.club