MySQL MAX()GROUP BY 3表

时间:2017-08-16 21:18:44

标签: mysql sql

我有3张桌子:

isset($_FILES['certificate'])

以下是示例数据:

CREATE TABLE IF NOT EXISTS sportsman (
    sportsman_id int NOT NULL AUTO_INCREMENT,
    sportsman_name varchar(255) NOT NULL,
    PRIMARY KEY (sportsman_id)
);

CREATE TABLE IF NOT EXISTS competition (
    competition_id int NOT NULL AUTO_INCREMENT,
    competition_name varchar(255) NOT NULL,
    PRIMARY KEY (competition_id)
);

CREATE TABLE IF NOT EXISTS results (
    competition_id int,
    sportsman_id int,
    result float,
    FOREIGN KEY (sportsman_id) REFERENCES sportsman(sportsman_id),
    FOREIGN KEY (competition_id) REFERENCES competition(competition_id)
);

我需要获得competition_name,max result,sportsman_name。

我的查询是:

INSERT INTO `sportsman` (`sportsman_name`) VALUES ('sportsman1');
INSERT INTO `sportsman` (`sportsman_name`) VALUES ('sportsman2');

INSERT INTO `competition` (`competition_name`) VALUES ('competition1');
INSERT INTO `competition` (`competition_name`) VALUES ('competition2');

INSERT INTO `results` (`competition_id`, `sportsman_id`, `result`) VALUES ('1', '1', '20');
INSERT INTO `results` (`competition_id`, `sportsman_id`, `result`) VALUES ('1', '2', '25');

INSERT INTO `results` (`competition_id`, `sportsman_id`, `result`) VALUES ('2', '1', '18');
INSERT INTO `results` (`competition_id`, `sportsman_id`, `result`) VALUES ('2', '2', '23');

它按competition_name分组,它找到最大结果。但它首先选择了sportsman_name。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

GROUP BY sportsman_name还可以在每场比赛中获得每个参赛者的MAX(结果)。

SELECT 
    c.`competition_name`, 
    MAX(r.`result`), 
    s.`sportsman_name`
FROM `competition` c
INNER JOIN `results` r ON c.`competition_id` = r.`competition_id`
INNER JOIN `sportsman` s ON s.`sportsman_id` = r.`sportsman_id` 
GROUP BY c.`competition_name`, s.`sportsman_name`;

Link to a live demo to try it out

如果你只想显示最高得分手的名字:

SELECT 
    c.`competition_name`, result, r.sportsman_id, sportsman_name
FROM
    `competition` c
        INNER JOIN
    `results` r ON c.`competition_id` = r.`competition_id`
        AND r.`sportsman_id` = (SELECT 
            rs.`sportsman_id`
        FROM
            results rs
        WHERE
            rs.`competition_id` = r.`competition_id`
        ORDER BY rs.`result` DESC
        LIMIT 1)
        INNER JOIN
    `sportsman` s ON s.sportsman_id = r.sportsman_id
GROUP BY c.`competition_name`;

Fiddle

答案 1 :(得分:0)

MySQL中最简单的方法是使用group_concat() / substring_index()

SELECT c.`competition_name`, MAX(r.`result`), 
       SUBSTRING_INDEX(GROUP_CONCAT(s.`sportsman_name` ORDER BY r.result DESC), ',', 1) as sportspersons_name
FROM `competition` c INNER JOIN
     `results` r
     ON c.`competition_id` = r.`competition_id` INNER JOIN
     `sportsman` s
     ON s.`sportsman_id` = r.`sportsman_id` 
GROUP BY c.`competition_name`;

这有一些限制。首先,如果竞争对手的名字可以有逗号,那么你需要另一个分隔符(例如'|');这是对查询的一个小调整。

其次,GROUP_CONCAT()的内部缓冲区的默认最大长度约为1,000个字符。对于您的样本数据,这不太可能是一个问题。但是这个限制很好(可以增加)。

两种替代方法可以解决这个问题。一个人使用额外的查询来获得最大的结果,然后再加入"加入其中。第二个使用变量。在大多数数据库中,您只需使用ROW_NUMBER(),但MySQL不支持ANSI标准函数。

答案 2 :(得分:0)

我的同事给我发了另一个问题的解决方案。也许它会帮助某人

SELECT 
    c.competition_name,
    r.result,
    s.sportsman_name
FROM competition c 
JOIN (SELECT 
    MAX(result) result, competition_id
FROM results
GROUP BY competition_id 
) AS temp ON temp.competition_id = c.competition_id
JOIN results r ON r.result = temp.result AND r.competition_id = temp.competition_id
JOIN sportsman s ON s.sportsman_id = r.sportsman_id
WHERE temp.competition_id IS NOT NULL;