Як вибрати рядок з максимальним значенням у таблиці mysql

У мене є така таблиця

Структура таблиці:

CREATE TABLE IF NOT EXISTS `people` ( 
`name` varchar(10) NOT NULL, 
`age` smallint(5) unsigned NOT NULL, 
PRIMARY KEY (`name`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Вставити деякі значення:

INSERT INTO `people` (`name`, `age`) VALUES 
('bob', 13), 
('john', 25), 
('steve', 8), 
('sue', 13); 

Виконаний запит:

SELECT MAX(  `age` ) ,  `name` FROM  `people` WHERE 1

Очікуваний результат:

25, John

Генерований результат

25, bob

Ми можемо це досягти, використовуючи цей запит

SELECT `age`,  `name` FROM  `people` ORDER BY age DESC LIMIT 1

Запитання 1: що я тут помилився і чому ця функція MAX не повертає відповідну інформацію про рядку?

Запитання 2: Який з них можна використовувати, щоб збільшити функцію MAX або ORDER BY?

13
Для цього тривіального прикладу відповідь очевидно полягає в тому, що ORDER BY. Для більш складної проблеми - так званого запиту GROUPWISE MAX, це щось з FAQ, і безліч відповідей вже було надано.
додано Автор Strawberry, джерело

7 Відповіді

Питання 1: що я тут помилився і чому ця функція MAX не повертає відповідну інформацію про рядка?

Потрібно ознайомитись зі статтею group .

MySQL є набагато більш дозвільним, ніж це, вводячи плутанину в процес. В основному, будь-який стовпець без сукупності повинен бути включений в групу . Але MySQL синтаксичний цукор дозволяє "забути" стовпці. Коли ви робите, MySQL виділяє довільну величину з набору, що групується за. У вашому випадку першим рядком у наборі є bob , тому він повертається.

Запитання 2: Який з них можна використовувати, щоб збільшити функцію MAX або ORDER BY?

Ваша перша заява (використовуючи max() без групи ) просто неправильна.

Якщо ви хочете, щоб один із найстаріших користувачів, то правильний спосіб продовжити замовлення за віком обмеження віку 1 .

Якщо ви хочете, щоб усі найстаріші користувачі, вам потрібен підселект:

SELECT p.* FROM people p WHERE p.age = (select max(subp.age) from people subp);
19
додано
Або - вони дають різні результати. Для продуктивності ви хочете мати індекс age .
додано Автор Denis de Bernardy, джерело
Я погоджуюся, який з них хороший для підвищення продуктивності, порядок за умовчанням або підзапит
додано Автор Sundar, джерело

спробуйте це

SELECT age, name FROM  `people` where age = (SELECT max(age) FROM  people)
10
додано
якщо ви використовуєте будь-який індекс у вашій таблиці, то скористайтеся пунктом "Порядок", інакше підзапит буде кращим, ніж "Замовлення за пропозицією" Спасибо "
додано Автор Napster, джерело
Я згоден з вашою відповіддю, але який з них хороший для підвищення продуктивності, порядок за умовчанням або підзапит
додано Автор Sundar, джерело

Ще одне рішення, яке не використовує функції aggregate і групування:

SELECT * FROM people ORDER BY age DESC LIMIT 1

7
додано

Чого я помилився тут і чому ця функція MAX не повертає відповідну інформацію про рядка?

MAX повертає правильне значення - але інший стовпчик, який ви виберете, просто дає вам "випадкове" значення.

Вибір стовпців, які не входять до GROUPing (і я думаю, що неявний GROUP BY виконується тут, оскільки ви використовуєте функцію агрегації) є незаконним в суворій SQL-MySQL однак ігнорує це (залежно від конфігурації сервера) і дає вам значення з "випадковий" рядок у таких випадках.


Alternative approaches are described here: The Rows Holding the Group-wise Maximum of a Certain Column

3
додано

Question 1 : If you really want to use the MAX() you could try this SELECT age, name FROM people WHERE age IN (SELECT MAX(age) FROM people);

Питання 2: Я думаю, що це залежить від моєї пропозиції в питанні 1, ви двічі виконуєте запит, але в наданому нами вирішенні ORDER BY база даних виконала сортування, як процедура.

0
додано

MAX - сукупна функція . Це означає, що MySQL об'єднує всі записи та обробляє їх так, якби вони були одними в наборі результатів. Оскільки ви не вказали, як стовпець назви повинен бути згрупований, результат може бути несподіваним. ORDER BY - це чудовий спосіб досягти бажаного результату. Просто не забудьте додати індекс до віку тому продуктивність не впливає, оскільки таблиця зростає.

0
додано

Існує цікава альтернатива, яка працює тільки на MySql!

SELECT `Name`, `Age` FROM 
(SELECT `Name`, `Age`, 1 AS `foo`
FROM `People`
ORDER BY `Age` DESC) AS `x`
GROUP BY `foo`

Це працює тому, що MySql повертає перший рядок, коли в даному стовпці не застосовується функція агрегації

Here is the link: http://tominology.blogspot.com.br/2014/10/sql-row-with-max-value.html

0
додано