2010-03-16 3 views
2

MySQL v5.0.58. 간결함을 위해 생략 외부 키 제한 조건 등 및 기타 비 관련 세부'WITH'를 사용할 수없는 경우 반복되는 서브 쿼리 피하기

테이블 :

CREATE TABLE `fixture` (
    `id` int(11) NOT NULL auto_increment, 
    `competition_id` int(11) NOT NULL, 
    `name` varchar(50) NOT NULL, 
    `scheduled` datetime default NULL, 
    `played` datetime default NULL, 
    PRIMARY KEY (`id`) 
); 

CREATE TABLE `result` (
    `id` int(11) NOT NULL auto_increment, 
    `fixture_id` int(11) NOT NULL, 
    `team_id` int(11) NOT NULL, 
    `score` int(11) NOT NULL, 
    `place` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

CREATE TABLE `team` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(50) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

장소 :

  • 무승부는 result을 설정합니다. place to 0
  • result. place에는 1 위, 2 위 등을 나타내는 정수가 포함됩니다.

주어진 팀의 주어진 경기에서 가장 최근에 재생 된 결과를 설명하는 문자열을 반환하는 작업입니다. 형식은 팀이 승리했다면 "팀 X, 팀 Y"를, 주어진 팀이 손실되면 "팀 X에게", 추첨이 있었다면 "팀 X와 함께"가져와야합니다. 그리고 예, 이론적으로 조명기 당 2 개 이상의 팀이있을 수 있습니다 (1 v 1이 가장 일반적인 경우 임).

이 작동하지만, 정말 비효율적 인 느낌 :

SELECT CONCAT(
    (SELECT CASE `result`.`place` 
     WHEN 0 THEN "drew with" 
     WHEN 1 THEN "def" 
     ELSE "lost to" 
     END 
    FROM `result` 
    WHERE `result`.`fixture_id` = 
     (SELECT `fixture`.`id` FROM `fixture` 
     LEFT JOIN `result` ON `result`.`fixture_id` = `fixture`.`id` 
     WHERE `fixture`.`competition_id` = 2 
     AND `result`.`team_id` = 1 
     ORDER BY `fixture`.`played` DESC 
     LIMIT 1) 
    AND `result`.`team_id` = 1), 
    ' ', 
    (SELECT GROUP_CONCAT(`team`.`name`) 
    FROM `fixture` 
    LEFT JOIN `result` ON `result`.`fixture_id` = `fixture`.`id` 
    LEFT JOIN `team` ON `result`.`team_id` = `team`.`id` 
    WHERE `fixture`.`id` = 
     (SELECT `fixture`.`id` FROM `fixture` 
     LEFT JOIN `result` ON `result`.`fixture_id` = `fixture`.`id` 
     WHERE `fixture`.`competition_id` = 2 
     AND `result`.`team_id` = 1 
     ORDER BY `fixture`.`played` DESC 
     LIMIT 1) 
    AND `team`.`id` != 1) 
) 

난 정말 분명 뭔가를 놓친, 또는 단순히 하나 개의 쿼리에서이 작업을 수행하려고하지 않겠습니까? 아니면 현재의 어려움이 가난한 테이블 디자인을 반영합니까?

+0

"잃어버린"사례는 실제로 승리 팀만 표시해야하기 때문에보다 신중하게 처리해야합니다. –

+0

경기에 참가할 팀 수는 몇 개입니까? – outis

+0

나는 그것에 대한 경계가 없기 때문에 조명기가 결과와 분리되어있는 현재의 테이블 디자인을 사용합니다. 일부 게임 (여기에서 컴퓨터 게임을 말하는 중입니다)에는 경기 당 3 개 이상의면이 있습니다 (예 : Dawn of War와 같은 RTS). –

답변

1

원하는 데이터 (대상 팀에 대해서는 팀 이름 및 place)를 선택한 다음이를 조합 해보십시오. 고정 당 두 팀의 경우 : 다른 하위 쿼리도 일하는 것이 비록

SELECT CASE `recent`.`place` 
     WHEN 0 THEN CONCAT("drew with ", other_name) 
     WHEN 1 THEN CONCAT("def ", other_name, ", ", targ_name) 
     ELSE CONCAT("lost to ", other_name) 
    END 
FROM (SELECT rtarg.place, targ.name AS targ_name, other.name AS other_name 
     FROM `fixture` 
     JOIN `result` AS rtarg ON `rtarg`.`fixture_id` = `fixture`.`id` 
     JOIN `team` AS targ ON `rtarg`.`team_id` = `targ`.`id` 
     JOIN `result` AS rother ON `rother`.`fixture_id` = `fixture`.`id` 
     JOIN `team` AS other ON `rother`.`team_id` = `other`.`id` 
     WHERE `fixture`.`competition_id` = 2 
      AND `rtarg`.`team_id` = @targ 
      AND `rother`.`team_id` != @targ 
     ORDER BY `fixture`.`played` DESC 
     LIMIT 1) AS `recent`; 

고정 당 두 개 이상의 팀을 처리, 최소한의 변경으로 수행 할 수 있습니다.

SELECT CASE `recent`.`place` 
     WHEN 0 THEN CONCAT("drew with ", other_names) 
     WHEN 1 THEN CONCAT("def ", other_names, "; ", targ_name) 
     ELSE CONCAT("lost to ", other_names) 
    END 
FROM (SELECT rtarg.place, targ.name AS targ_name, GROUP_CONCAT(other.name SEPARATOR ', ') AS other_names 
     FROM `fixture` 
     JOIN `result` AS rtarg ON `rtarg`.`fixture_id` = `fixture`.`id` 
     JOIN `team` AS targ ON `rtarg`.`team_id` = `targ`.`id` 
     JOIN `result` AS rother ON `rother`.`fixture_id` = `fixture`.`id` 
     JOIN `team` AS other ON `rother`.`team_id` = `other`.`id` 
     WHERE `fixture`.`competition_id` = 2 
      AND `targ`.`id` = @targ 
      AND `rother`.`team_id` != @targ 
      AND ((rtarg.place<=1 AND rother.place >= rtarg.place) 
      OR (rtarg.place>1 AND rother.place < rtarg.place)) 
     GROUP BY fixture.id 
     ORDER BY `fixture`.`played` DESC 
     LIMIT 1 
) AS recent; 

조명기 당 2 개 이상의 팀에 대한 결과 형식은 지정되지 않았으므로, 추가 조정이 순서대로 이루어질 수 있습니다.

+0

나는 접근법을 좋아하지만 안타깝게도 조명기 당 두 개 이상의 팀이있는 경우를 고려하지 않습니다. 내가 잘못 이해하지 않았다면? –

+0

당신은 그것을 가지고 있습니다. 조명기 당 2 개 이상의 팀에 대한 다른 쿼리로 곧 답변을 업데이트하겠습니다. – outis

+0

도움을 주셔서 대단히 감사드립니다! –

관련 문제