2017-08-16 77 views
2

我有3個表:的MySQL MAX()GROUP BY 3個表

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) 
); 

這裏是樣本數據:

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。

我的查詢是:

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`; 

它按competition_name,發現最大的結果。但它選擇了第一個sportsman_name。

有什麼建議嗎?

+1

你想什麼要發生的,而不是 – Strawberry

+0

可能的複製[取它具有最高值的列行(https://stackoverflow.com/questions/121387/fetch-該行具有最大值的列) – Uueerdo

回答

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

+0

感謝@Exomus小提琴。 – ishegg

+0

我認爲OP希望運動員的名字有最大的效果。 –

+0

哦......我明白了。我已經更新了答案,以說明如何實現這一點。 – ishegg

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個字符。對於您的示例數據,這不可能是一個問題。但限制是很好的知道(可以增加)。

兩種替代方法解決這個問題。一個使用額外的查詢來獲得最大的結果,並返回「join」。第二個使用變量。在大多數數據庫中,您只需使用ROW_NUMBER(),但MySQL不支持ANSI標準功能。

+0

爲什麼你留下GROUP_CONCAT的最後一個參數爲空?查詢工作正常,如果我把1作爲最後一個參數。 '',','1')as sportspersons_name' –

+0

@ sta.ck。 。 。這應該是'1',沒有引號。 –

+0

@ sta.ck。 。 。這個版本應該比在子查詢中使用'join'和'group by'的版本更高效一些。 –

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; 
+0

只是擡頭:你只能接受一個答案。 – ishegg

+0

好的。然後,我會接受你的答案,因爲1.你是來自於計算器,並且2.你的解決方案更通用。 –

+0

我不是從堆棧溢出:)只是接受最有幫助的答案。我在另一個線程上問了一個問題!如果可以,請回答。 – ishegg