如何为同一条记录计算不同的平均值?

时间:2018-07-15 10:05:02

标签: mysql sql

我有一个venue的列表,其中不同的teams可以播放match。现在,每个team的{​​{1}}可以得到match的{​​{1}},所以我正在尝试计算{{1}的attendance },问题是我将结果分组为一个venue,这是因为我使用了聚合函数,而我被迫使用AVG,查询应该返回相同的{{1} },但当然要使用不同的attendance和不同的venue

查询

GROUP BY

数据样本

匹配

venue

场地

teams

team_info

AVG attendance

团队

SELECT m.venue_id,
MIN(m.venue_attendance) AS min_attendance,
MAX(m.venue_attendance) AS max_attendance,
SUM(m.venue_attendance) AS venue_sum,
v.name AS venue_name,
ROUND(AVG(m.venue_attendance), 2) AS average,
v.capacity, t.name AS team_name
FROM `match` m
INNER JOIN venue v ON v.id = m.venue_id
INNER JOIN team_info i ON i.venue_id = m.venue_id
INNER JOIN team t ON t.id = i.team_id
WHERE m.round_id = :round_id
GROUP BY m.venue_id, t.name
ORDER BY average DESC

输出

id      | round_id | home_team_id | away_team_id | venue_id | venue_attendance
2506177     28            70             71           10           6000
2506195     28            70             76           10            500
2506204     28            70             69           10           2000
2506219     28            70             72           10            500
2506230     28            70           2517           10            300
2506235     28            70           2522           10            500
2506244     28            70          10049           10            400
2506252     28            70          12573           10           6000
2506258     28          2518             70           10           4500
2506267     28            70             71           10           1000
2506285     28            70             76           10            700
2506294     28            70             69           10           1500
2506303     28            70           2518           10           2500
2506309     28            70             72           10           1200
2506320     28            70           2517           10           1200
2506325     28            70           2522           10            800
2506334     28            70          10049           10           5500
2506342     28            70          12573           10           1000

预期产量

id | name                 | address          | zip_code | city    | phone |
10   Stadiumi Loro Boriçi  Rruga Musa Luli 1    4000      Shkodër   NULL

如您所见,team_id | venue_id | 70 10 2518 10 仅在 id | name 70 Skënderbeu Korçë 2518 Vllaznia Shkodër 在家比赛时,在{ "venue_id": "10", "min_attendance": "300", "max_attendance": "6000", "venue_sum": "36100", "venue_name": "Stadiumi Loro Boriçi", "average": "2005.56", "capacity": "16000", "team_name": "Vllaznia Shkodër" } 场上进行计算,平均值是{{1}的总数},例如{ "venue_id": "10", "min_attendance": "300", "max_attendance": "6000", "venue_sum": "31600", "venue_name": "Stadiumi Loro Boriçi", "average": "1858", "capacity": "16000", "team_name": "Vllaznia Shkodër" }, { "venue_id": "10", "min_attendance": "4500", "max_attendance": "4500", "venue_sum": "4500", "venue_name": "Stadiumi Loro Boriçi", "average": "4500", "capacity": "16000", "team_name": "Skënderbeu Korçe" } 的平均值为:31600/17 = 1858。

完整的数据库:https://files.fm/u/2xwgkaxz

要访问示例中的数据,只需运行:

venue_sum

我该如何处理?

scaisEdge答案

scaisEdge的解决方案建议仅适用于详细说明结果,实际上,现在的平均值是正确的。的 主要问题仍然存在,事实上scaisEdge查询的实际结果是:

team

还有其他场所,但是我想像以前所说的那样集中注意力 我需要为不同的团队返回同一地点,所以我也应该得到:

home_team_id

但我只能得到:

venue_sum / matches played by the team

因此预期的最终结果必须包括以下内容:

Vllaznia Shkodër

4 个答案:

答案 0 :(得分:2)

您应该加入home_team_id

  SELECT m.venue_id,
  MIN(m.venue_attendance) AS min_attendance,
  MAX(m.venue_attendance) AS max_attendance,
  SUM(m.venue_attendance) AS venue_sum,
  v.name AS venue_name,
  ROUND(AVG(m.venue_attendance), 2) AS average,
  v.capacity, t.name AS team_name
  FROM `match` m
  INNER JOIN venue v ON v.id = m.venue_id
  INNER JOIN team_info i ON i.venue_id = m.venue_id and i.team_id = m.home_team_id
  INNER JOIN team t ON t.id = m.home_team_id
  WHERE m.round_id = :round_id
  GROUP BY m.venue_id, t.name
  ORDER BY average DESC

答案 1 :(得分:2)

您仅使用team_info来加入venue_id表。这样,match中的每一行都将与team_info中的每个团队一起加入。您应该添加条件i.team_id = m.home_team_id,以仅将JOIN限制为主队:

SELECT m.venue_id,
MIN(m.venue_attendance) AS min_attendance,
MAX(m.venue_attendance) AS max_attendance,
SUM(m.venue_attendance) AS venue_sum,
v.name AS venue_name,
ROUND(AVG(m.venue_attendance), 2) AS average,
-- v.capacity, -- no such column in sample data
t.name AS team_name
FROM `match` m
INNER JOIN venue v ON v.id = m.venue_id
INNER JOIN team_info i 
  ON  i.venue_id = m.venue_id
  AND i.team_id  = m.home_team_id -- this is the fix
INNER JOIN team t ON t.id = i.team_id
WHERE m.round_id = 28
GROUP BY m.venue_id, t.name
ORDER BY average DESC

结果:

| venue_id | min_attendance | max_attendance | venue_sum |           venue_name | average |        team_name |
|----------|----------------|----------------|-----------|----------------------|---------|------------------|
|       10 |           4500 |           4500 |      4500 | Stadiumi Loro Boriçi |    4500 | Vllaznia Shkodër |
|       10 |            300 |           6000 |     31600 | Stadiumi Loro Boriçi | 1858.82 | Skënderbeu Korçë |

提琴:http://sqlfiddle.com/#!9/9aaf7c9/1

但是您可能只跳过team_info表并将team表直接连接到match

SELECT m.venue_id,
MIN(m.venue_attendance) AS min_attendance,
MAX(m.venue_attendance) AS max_attendance,
SUM(m.venue_attendance) AS venue_sum,
v.name AS venue_name,
ROUND(AVG(m.venue_attendance), 2) AS average,
-- v.capacity, -- no such column in sample data
t.name AS team_name
FROM `match` m
INNER JOIN venue v ON v.id = m.venue_id
INNER JOIN team t ON t.id = m.home_team_id  -- this is the fix
WHERE m.round_id = 28
GROUP BY m.venue_id, t.name
ORDER BY average DESC

结果是相同的。

答案 2 :(得分:1)

我认为要在查询中多次访问体育场,您必须使用分析函数而不是group by子句。

SELECT
    venue_id,
    min_attendance,
    max_attendance,
    venue_sum,
    venue_name,
    round(average,2) AS average,
    team_name
FROM
    (
        SELECT
            m.venue_id,
            MIN(m.venue_attendance) OVER(
                PARTITION BY home_team_id
            ) AS min_attendance,
            MAX(m.venue_attendance) OVER(
                PARTITION BY home_team_id
            ) AS max_attendance,
            SUM(m.venue_attendance) OVER(
                PARTITION BY home_team_id
            ) AS venue_sum,
            v.name AS venue_name,
            AVG(m.venue_attendance) OVER(
                PARTITION BY home_team_id
                ORDER BY
                    NULL
            ) AS average,
  --M.capacity, 
            t.name AS team_name
        FROM
            match m
            INNER JOIN venue v ON v.id = m.venue_id
            INNER JOIN team_info i ON i.venue_id = m.venue_id
                                      AND i.team_id = m.home_team_id
            INNER JOIN team t ON t.id = m.home_team_id
        WHERE
            m.round_id =:round_id
    )
ORDER BY
    average DESC;

希望有帮助。

问候 安奇

答案 3 :(得分:1)

如果每个团队都希望这样做,则需要将每一行分为两行-一列用于主队,一列用于客队。

以下是每个团队每个场地的结果:

select venue_id, team_id,
       min(venue_attendance),
       max(venue_attendance),
       avg(venue_attendance)
from ((select m.venue_id, m.home_team_id as team_id, venue_attendance
       from match m
      ) union all
      (select m.venue_id, m.away_team_id as team_id, venue_attendance
       from match m
      )
     ) m
group by venue_id, team_id;

我将让您使用联接来获取查询的名称和容量。

Here是简化的SQL小提琴,按场所和团队显示结果。与上述查询的唯一区别是matches而不是match,因为后者是保留字。