MySQL子查询JOIN

时间:2014-11-28 22:07:52

标签: mysql sql

尝试组合一个SQL查询,该查询将从一个表中获取COUNT值,从另一个表中获取SUM的AVG。这两个查询分开工作,但我无法弄清楚如何正确地将它们合并为一个。

这两个问题 - 第一个被缩短为两个总和:

SELECT SUM(CASE WHEN `eventClass`='GOAL' AND `player1ID`=001 THEN 1 ELSE 0 END) goals,
SUM(CASE WHEN `eventClass`='GOAL' AND `player2ID`=001 THEN 1 ELSE 0 END) assists
FROM `plays`

&安培;

SELECT ROUND(AVG(`toi`)) AS avgTime 
FROM ( 
    SELECT SUM(TIME_TO_SEC(`shiftDuration`)) AS toi 
    FROM `shifts` 
    WHERE `playerID`=001 
    GROUP BY `gameNo`
) t;

现在我已尝试了一些加入的东西,但我不知道加入它们的内容,因为我在第一个查询中我在两列中的一列中寻找我的搜索值001,具体取决于行。

非常感谢任何帮助!

安德鲁


示例数据:

table `plays`:
+--------+--------+------------+-----------+-----------+
| playNo | gameNo | eventClass | player1ID | player2ID |
+--------+--------+------------+-----------+-----------+
|      1 |      1 |   GOAL     |   001     |    002    |
|    210 |      3 |   GOAL     |   003     |    001    |
+--------+--------+------------+-----------+-----------+

table `shifts`:
+---------+--------+----------+---------------+
| shiftNo | gameNo | playerID | shiftDuration |
+---------+--------+----------+---------------+
|       1 |      1 |   001    |      65       |
|       2 |      1 |   001    |      38       |
|      12 |      1 |   002    |      47       |
|      22 |      3 |   001    |      13       |
+------=--+--------+----------+---------------+

现在我想把游戏中所有玩家001轮换的总和作为游戏总数;这是我想输出的所有这些游戏总数的平均值。

所需的输出 - 目标和助攻是001的全场比赛,而avgTime是每场比赛的平均值。在这里,我们将在几秒钟内完成标记。

+-------+-------+---------+---------+
| games | goals | assists | avgTime |
+-------+-------+---------+---------+
|   3   |  2    |   1     |   800   |
+-------+-------+---------+---------+

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用子查询或cross join

SELECT p.goals, p.assist, s.avgTime
FROM (SELECT SUM(CASE WHEN `eventClass`='GOAL' AND `player1ID`=001 THEN 1 ELSE 0 END) goals,
             SUM(CASE WHEN `eventClass`='GOAL' AND `player2ID`=001 THEN 1 ELSE 0 END) assists
      FROM `plays`
     ) p CROSS JOIN
     (SELECT ROUND(AVG(`toi`)) AS avgTime 
      FROM (SELECT SUM(TIME_TO_SEC(`shiftDuration`)) AS toi 
            FROM `shifts` 
            WHERE `playerID`=001 
            GROUP BY `gameNo`
           ) s
     ) s;

我不清楚games列的来源。

请勿尝试仅使用join和单个聚合执行此操作。您总结了两个不同的维度 - 并且在聚合之前进行联接往往会导致不需要的笛卡尔积。

答案 1 :(得分:0)

这不像@GordonLinoff那样紧凑,但一次只能处理多个玩家,并按个别游戏分解:

SELECT R.gameNo, R.playerID, R.goals, R.assists, S.toi FROM (
  SELECT P1.gameNo, P1.playerID, P1.goals, P2.assists FROM (
    SELECT
      gameNo
      , player1ID playerID
      , COUNT(playNo) goals
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY gameNo, player1ID
  ) P1
  LEFT JOIN (
    SELECT
      gameNo
      , player2ID playerID
      , COUNT(playNo) assists
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY gameNo, player2ID
  ) P2 ON P1.gameNo = P2.gameNo AND P1.playerID = P2.playerID
  UNION
  SELECT P2.gameNo, P2.playerID, P1.goals, P2.assists FROM (
    SELECT
      gameNo
      , player1ID playerID
      , COUNT(playNo) goals
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY gameNo, player1ID
  ) P1
  RIGHT JOIN (
    SELECT
      gameNo
      , player2ID playerID
      , COUNT(playNo) assists
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY gameNo, player2ID
  ) P2 ON P1.gameNo = P2.gameNo AND P1.playerID = P2.playerID
) R
JOIN (
  SELECT
    gameNo
    , playerID
    , SUM(shiftDuration) AS toi 
  FROM Shifts
  GROUP BY gameNo, playerID
) S
ON R.gameNo = S.gameNo AND R.playerID = S. playerID
ORDER BY gameNo, playerID
;

SQL Fiddle

我放弃TIME_TO_SEC(根据给定的数据,这对我来说似乎没有任何影响),并且没有AVG以便返回在相应游戏中播放的时间。

但显然,你想要总体总数(因此AVG)。所以 - 这应该是你问题的答案:

SELECT R.playerID, R.goals, R.assists, S.avgTime FROM (
  SELECT P1.playerID, P1.goals, P2.assists FROM (
    SELECT
      player1ID playerID
      , COUNT(playNo) goals
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY player1ID
  ) P1
  LEFT JOIN (
    SELECT
      player2ID playerID
      , COUNT(playNo) assists
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY player2ID
  ) P2 ON P1.playerID = P2.playerID
  UNION
  SELECT P2.playerID, P1.goals, P2.assists FROM (
    SELECT
      player1ID playerID
      , COUNT(playNo) goals
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY gameNo, player1ID
  ) P1
  RIGHT JOIN (
    SELECT
      player2ID playerID
      , COUNT(playNo) assists
    FROM Plays
    WHERE eventClass = 'GOAL'
    GROUP BY player2ID
  ) P2 ON P1.playerID = P2.playerID
) R
JOIN (
    SELECT S.playerID, ROUND(AVG(S.toi)) avgTime
    FROM (
      SELECT
        gameNo
        , playerID
        , SUM(shiftDuration) AS toi 
      FROM Shifts
      GROUP BY gameNo, playerID
    ) S
    GROUP BY S.playerID
) S
ON R.playerID = S. playerID
ORDER BY R.playerID
;

Updated SQL Fiddle

小提琴从上述陈述的各个部分开始,然后进入完整的装配。