制作得分表(硬)

时间:2015-08-05 18:54:40

标签: mysql sql

我需要你的帮助。

我有一个包含这样的架构的数据库:

队:

  • ID
  • 名称
  • fundation_date

配衬:

  • ID
  • 日期
  • id_local_team (团队的外键)
  • id_visit_team (团队的外键)
  • 获胜者('本地','访问','抽奖')

播放器:

  • ID
  • 名称
  • 职位('arq','def','med','del')
  • id_team

目标:

  • ID
  • id_match
  • id_player
  • 时间

我需要做(除其他事项外)这个:

按球队展示:比赛,获胜比赛和抽签比赛(在不同的栏目中)

我有这样的事情:

SELECT t.name,
SUM(CASE t.id WHEN m.id_local_team THEN 1 WHEN m.id_visit_team THEN 1 ELSE 0 END) AS played,
SUM(CASE (CASE m.winner
              WHEN 'local' THEN m.id_local_team
              WHEN 'visit' THEN m.id_visit_team 
              ELSE NULL END) 
        WHEN t.id THEN 1 
        ELSE 0 END) AS winned,
SUM(CASE m.winner WHEN 'draw' THEN 1 ELSE 0 END) AS drawn
FROM teams AS t
INNER JOIN matchs AS m
    ON (t.id = m.id_local_team OR t.id = m.id_visit_team)
GROUP BY t.name;

但这给了我错误的结果。比如,总共有8场比赛,而(4)球队将返回12场,9场或10场比赛(总共43场比赛),共16场比赛和总共10场比赛。以上都是8。

发生了什么事?

在完整查询中,我还有两个内部联接:

INNER JOIN players AS p
    ON (p.id_team = t.id)
INNER JOIN goals AS g
    ON (p.id = g.id_jugador)

我认为这与最后一些没有任何关系。我知道(想想?)我没有正确加入比赛。

我很感激,如果你已经把它做到了这一点!

真正的架构实际上是西班牙语,实际上是西班牙语(对不起那些家伙)但是这里有所有的魔力:

SCHEMA

| equipos | CREATE TABLE `equipos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(180) NOT NULL,
  `f_fundacion` date DEFAULT NULL,
  PRIMARY KEY (`id`)
)
| partidos | CREATE TABLE `partidos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fecha` datetime DEFAULT NULL,
  `id_equipo_local` int(11) DEFAULT NULL,
  `id_equipo_visitante` int(11) DEFAULT NULL,
  `ganador` enum('local','visitante','empate') DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_partidos_equipos_1` (`id_equipo_local`),
  KEY `fk_partidos_equipos_2` (`id_equipo_visitante`),
  CONSTRAINT `fk_partidos_equipos_1` FOREIGN KEY (`id_equipo_local`) REFERENCES `equipos` (`id`),
  CONSTRAINT `fk_partidos_equipos_2` FOREIGN KEY (`id_equipo_visitante`) REFERENCES `equipos` (`id`)
)

QUERY

SELECT e.nombre, 
    SUM(CASE e.id WHEN p.id_equipo_visitante THEN 1 WHEN p.id_equipo_local THEN 1 ELSE 0 END) AS jugados, 
    SUM(CASE (CASE ganador 
              WHEN 'local' THEN p.id_equipo_local 
              WHEN 'visitante' THEN p.id_equipo_visitante 
              ELSE NULL END) 
        WHEN e.id THEN 1 
        ELSE 0 END) AS ganados,
    SUM(CASE ganador WHEN 'empate' THEN 1 ELSE 0 END) AS empatados,
    SUM(CASE (CASE ganador 
              WHEN 'local' THEN p.id_equipo_local 
              WHEN 'visitante' THEN p.id_equipo_visitante 
              ELSE NULL END) 
        WHEN e.id THEN 1 
        ELSE 0 END) * 3 + SUM(CASE ganador WHEN 'empate' THEN 1 ELSE 0 END) AS puntos,
    COUNT(DISTINCT g.id) AS goles_a_favor
    FROM equipos AS e
    INNER JOIN partidos AS p
        ON (e.id = p.id_equipo_visitante OR e.id = p.id_equipo_local)
    INNER JOIN jugadores AS j
        ON (j.id_equipo = e.id)
    INNER JOIN goles AS g
        ON (j.id = g.id_jugador)
    GROUP BY e.nombre;

结果

+----------------------------------+---------+---------+-----------+--------+---------------+
| nombre                           | jugados | ganados | empatados | puntos | goles_a_favor |
+----------------------------------+---------+---------+-----------+--------+---------------+
| Club Atlético All Boys           |      12 |       6 |         3 |     21 |             3 |
| Club Atlético Chacarita Juniors  |      12 |       3 |         0 |      9 |             3 |
| Club Atlético Ferrocarril Oeste  |       9 |       3 |         3 |     12 |             3 |
| Club Atlético Tucumán            |      10 |       4 |         4 |     16 |             2 |
+----------------------------------+---------+---------+-----------+--------+---------------+

2 个答案:

答案 0 :(得分:1)

您说完整查询包含与给定匹配中的每个目标的联接。这将导致每个匹配被计数N次的情况,其中N是匹配中的目标数。所以对于0-0战平,比赛根本不会被计算,对于1-0的比赛,比赛对主队计算一次,对于客队计为零次,主队为1-2次两次访问团队。

要检查赞成的目标数量,您应首先使用子查询或视图计算每场比赛的目标余额,然后加入该目标。然后你不会因为加入玩家表而导致问题。

答案 1 :(得分:0)

看起来匹配JOIN是一个问题。因此,您每场比赛至少匹配两次,一次为主队,一次为客队,但这并不能解释显示的43场比赛。是否有可能看到全套结果?有时SQL内容可以触摸调试而无需访问表本身,但至少看到结果和重复的内容可能会有所帮助。

你可能只想参加胜利的球队 - 这应该减少一半。实际上,既然你似乎试图获取匹配信息,我会选择数据来自匹配而不是团队。从表中选择将限制所选行总数的表总是最好的选择,然后从那里加入。