Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MySQL > Выборка строк с максимальным значением столбца


Автор: ZMaximI 18.12.2007, 18:29
Добрый день!

Помогите, пожалуйста решить проблему.Есть таблица, например :

-------------------------------------
| ID   |    A      |    B    |    C    |
-------------------------------------
|   1  |     1      |   a    |     b    |
|   2  |     2      |   a    |     b     |
|   3  |     3      |   b     |    c     |
|   4  |     4      |   b    |     c    |
.....

Нужно выбрать все записи с максимальным значением столбца "А" по столбцу "B" ..
Чтобы получилось :

-------------------------------------
| ID   |    A      |    B    |    C    |
-------------------------------------
|   2  |     2      |   a    |     b     |
|   4  |     4      |   b    |     c    |
.....

я что-то туплю ....
Подскажите, как сделать такой SELECT ?

Спасибо.


Автор: Akina 18.12.2007, 18:45
Цитата

MIN([DISTINCT] expr) , MAX([DISTINCT] expr) 

Returns the minimum or maximum value of expr. MIN() and MAX() may take a string argument; in such cases they return the minimum or maximum string value. See Section 7.4.5, “How MySQL Uses Indexes”. The DISTINCT keyword can be used as of MySQL 5.0.0 to find the minimum or maximum of the distinct values of expr; this is supported, but produces the same result as omitting DISTINCT. 



mysql> SELECT student_name, MIN(test_score), MAX(test_score)
    ->        FROM student
    ->        GROUP BY student_name;


For MIN(), MAX(), and other aggregate functions, MySQL currently compares ENUM and SET columns by their string value rather than by the string's relative position in the set. This differs from how ORDER BY compares them. This will be rectified. 

Так что сравнивай как обычные числа



Автор: Feldmarschall 18.12.2007, 18:48
если А - уникальные, то можно простой группировкой.
а если нет...

Добавлено через 1 минуту и 27 секунд
Akina, ты не получишь из этой выборки ни id, ни C
если они не нужны, а только А и В - то конечно

Автор: ZMaximI 18.12.2007, 18:51
извини, но что-то я не совсем понял ..., т.е. шансов на одну выборку нет ?

в том-то и дело, что "А" не унакально ..

Автор: Akina 18.12.2007, 18:56
Цитата(ZMaximI @  18.12.2007,  19:51 Найти цитируемый пост)
т.е. шансов на одну выборку нет ? 

Сколько угодно... если текущая версия MySQL (которую ты не озаботился указать) поддерживает подзапросы.

Автор: ZMaximI 18.12.2007, 18:58
извини MySQL 5.0

Автор: Feldmarschall 18.12.2007, 18:59
-------------------------------------
| ID   |    A      |    B    |    C    |
-------------------------------------
|   1  |     1      |   a    |     b    |
|   2  |     2      |   a    |     b     |
|   3  |     2      |   a    |     с     |

Такой вариант таблицы возможен?
если да, то какую запись выбирать из двух последних?

и ещё. если вместо "а и бэ сидели на трубе" были бы реальные данные и задачи, то отвечающим, возможно, было бы проще сориентироваться

Автор: ZMaximI 18.12.2007, 19:05
вот структура таблицы :

Код

CREATE TABLE `depo_calc_results` (
  `ID` int(10) unsigned NOT NULL auto_increment,
  `CALC_DATE` date NOT NULL default '0000-00-00',
  `CALC_TIME` time NOT NULL default '00:00:00',
  `CALC_PERIOD_BEGIN` date NOT NULL default '0000-00-00',
  `CALC_PERIOD_END` date NOT NULL default '0000-00-00',
  `DEPO_MAN1` int(11) NOT NULL default '0',
  `COM_LOC` double(15,2) NOT NULL default '0.00',
  `COM_GLOB` double(15,2) NOT NULL default '0.00',
  PRIMARY KEY  (`ID`)
)


в этой таблице храняться расчитанные данные за каждый день, НО пользователи могут запустить расчет несколько раз за один день ...
следовательно мне нужно выбрать последний расчет - выбрать все записи с максимальным значением CALC_DATE и CALC_TIME, при этом должна быть обязательная группировка по DEPO_MAN1, т.к. в этом поле данные будут повторяться с каждым запуском расчета ...

Автор: Feldmarschall 18.12.2007, 19:29
странная таблица. не укладывающаяся в реляционные каноны, как я их понимаю.
если пользователь что-то посчитать может - то почему сервер то же самое посчитать не может?
обычно бд не используется для хранения результатов вычислений. А только для хранения исходных данных для этих вычислений.

насколько я понимаю А в этом случае уникальны для одного Бэ
значит, можно по ним джойнить таблицу на саму себя и... стоп. зачем нам дата и тайм, если у нас есть айди. уникальный и максимальный.
то есть берем макс айди и по нему джойним всю строчку. если я ни в чем не ошибсо

Автор: Akina 18.12.2007, 19:48
Полностью согласен с Feldmarschall.
Но уж если уперлось - не понимаю, почему результаты расчета добавляются в таблицу итогов новой записью, вместо того чтобы заместить ее обновлением. 
А если надо хранить все итоги расчетов - то зачем плодить себе геморроя, когда можно добавить поле валидности данных, ставить там галку при вводе записи и снимать во всех записях с теми же учетными данными.

Автор: ZMaximI 19.12.2007, 10:05
по поводу хранения всех расчетов, я с вами согласен, но так поставлена задача ...
поле валидности, наверное лучший вариант, т.к. джойн таблицы самой на себя - будет достаточно медленно.

Всем спасибо, за идеи.

Автор: Feldmarschall 19.12.2007, 10:12
Скажем так, про медленно - это заблуждение. Если миллионы реляционных  СУБД до сих пор не загнулись, то, наверное, джойн - всё-таки, не такая ужасно медленная операция, как кажется.

Другое дело, что мой запрос все равно не будет работать, если подумать. Джойнить по агрегатному результату, вроде, нельзя.


Автор: Akina 19.12.2007, 10:55
Цитата(Feldmarschall @  19.12.2007,  11:12 Найти цитируемый пост)
Джойнить по агрегатному результату, вроде, нельзя.

В MySQL вполне можно... но это однозначный filesort

Автор: ZMaximI 19.12.2007, 16:20
Еще раз, всем спасибо.
Вопрос закрыт.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)