Нормализовано вне знаний MySQL? - PullRequest
0 голосов
/ 22 августа 2009

Я думаю, что нормализовал свою базу данных за пределами моих знаний SQL. :) Вот вопрос, с которым я борюсь из моего веб-приложения в снукер-лиге. Он рассчитывает общую статистику для высоких перерывов для команды из всех сезонов. В примере команды id 3.

select max(break_score) maxBreak,avg(break_score) avgBreak,
   count(break_score) breaks
from breaks
join matches on match_id=break_match
where break_player in (
select distinct player_id
from players
join team_members on player=player_id and team=3)
and (match_hometeam=3 or match_awayteam=3)

Таблица:

  • совпадений:
match_id int(11) auto_increment
match_hometeam int(11)
match_awayteam int(11)
match_date date
match_void tinyint(4)
match_status tinyint(4)
match_homescore tinyint(4)
match_awayscore tinyint(4)
match_league int(11)
  • перерывы:
break_id int(11) auto_increment
break_match int(11) foreign key to match_id
break_player int(11)
break_score tinyint(4)
break_clearance tinyint(4)
break_year int(11)
  • team_members: таблица «многие ко многим».
team int(11) foreign key to teams table
player int(11) foreign key to players table
year int(11) the year that the player played for the team

Запрос выше работает почти так, как задумано, за исключением одной проблемы. Если игрок играл за более чем одну команду, то в эту статистику включаются перерывы, которые он имеет для всех команд.

Если бы в таблице Breaks было дополнительное поле 'break_team', запрос был бы тривиальным. Итак, мой вопрос в два раза, может ли кто-нибудь помочь с правильным запросом, или я должен немного уменьшить нормализацию, чтобы помочь с этой статистикой? Когда пришло время для нормализации?

1 Ответ

2 голосов
/ 22 августа 2009

У меня нет легкодоступной установки MySQL, но, вероятно, вам нужно предложение EXISTS, попробуйте это и ответьте, если он позаботится о том, что вам нужно или нет:

select max(break_score) maxBreak, avg(break_score) avgBreak, count(break_score) breaks
from breaks
join matches on match_id=break_match
where exists(select 1
from players
join team_members on player=player_id and team=3
where break_year = year
and break_player = player_id
and (match_hometeam=3 or match_awayteam=3))
...