К списку форумов К списку вопросов
Запрос к mysql
mae
03.06.2004 - 22:28
Имеется таблица, где упрощённо говоря есть два поля: NF и I_NF. Оба они имеют тип int.
Нужно выбрать те строки, где поле NF должно оказаться уникальным (а это вообще говоря не так, всякие значения встречаются) при _максимальном_ значении поля I_NF для данного NF. То есть если имеется 5 уникальных значений NF из тысячи, то строк будет именно 5, данные в поле NF повторяться не будут, и в этих пяти строках поле I_NF будет принимать своё максимально возможное значение при данном значении NF.
Как это можно сделать?
Deflorator
1 - 03.06.2004 - 22:50
сделать поле ключевым
Уверенный
2 - 03.06.2004 - 23:45
select nf, max(i_nf) as max_i_nf
from your_table
group by nf;
 
Или я чего-то не понимаю?
mae
3 - 06.06.2004 - 01:27
Уверенный, нет, не так. Здесь получается, что выдаёт NF и максимальный I_NF для этого NF. А надо, чтоб выдавал _строку_, в которой находится максимальный I_NF для данного NF.
Воот. А за group by сенкс, я не знал об этой фиче. Только я не понял, разве нельзя 'group by' и 'order by' одновременно?
Wsc
4 - 06.06.2004 - 08:39
to 3:
Навскидку щаз не напишу, но смысл таков - выбрать всю строку, а условие для выполнения запроса добавить в оператор HAVING, который используется c GROUP, т.е. select * from table group by поле HAVING условие ORDER by условие
mae
5 - 06.06.2004 - 10:43
Всё-таки не выходит. Про having - он отбирает записи уже после группировки, а мне надо до.
Вот, меня полностью устроил бы такой запрос: select * from table order by I_NF desc group by NF.
Но он не прокатывает, потому что здесь сначала сортировка, а потом группировка. Показывает сообщение об ошибке. Но мне нужен именно такой запрос!
Ведь простой запрос по сути. Как его правильно написать?
Я подозреваю, что Уверенный пошёл по верному пути, т.к. максимальные значения I_NF мы уже имеем. Сейчас вытащить бы ещё строки.
Уверенный
6 - 06.06.2004 - 11:10
create table your_table (
  nf int,
  i_nf int,
  t_nf varchar(10));
 
insert into your_table (nf, i_nf, t_nf) values (1, 1, '111111');
insert into your_table (nf, i_nf, t_nf) values (1, 2, '222222');
insert into your_table (nf, i_nf, t_nf) values (1, 3, '333333');
insert into your_table (nf, i_nf, t_nf) values (1, 4, '444444');
insert into your_table (nf, i_nf, t_nf) values (1, 7, '555555');
insert into your_table (nf, i_nf, t_nf) values (2, 1, '666666');
insert into your_table (nf, i_nf, t_nf) values (2, 2, '777777');
insert into your_table (nf, i_nf, t_nf) values (2, 3, '888888');
insert into your_table (nf, i_nf, t_nf) values (2, 4, '999999');
insert into your_table (nf, i_nf, t_nf) values (2, 5, 'AAAAAA');
 
create table tmp as
  select nf, max(i_nf) as max_i_nf
     from your_table
     group by nf;
 
select your_table.*
from your_table, tmp
where your_table.nf=tmp.nf
  and your_table.i_nf=tmp.max_i_nf
order by nf;
 
-------------------------------
Если бы база была не mysql, а оракл или постгрес, можно было бы обойтись без временной таблички, а mysql не поддерживает такие запросы:
 
select * from your_table, (select ... group by...) tmp
where your_table.nf=tmp.nf
  and your_table.i_nf=tmp.max_i_nf
order by nf;
 
>Только я не понял, разве нельзя 'group by' и 'order by' одновременно?
 
Можно, но group by сам делает order by по тем полям, по которым group by. Если нужен другой ордер - пожалуйста используй еще и order by.
Уверенный
7 - 06.06.2004 - 11:12
Да, у меня запрос из предыдущего поста возвращает это:
 
nf i_nf t_nf
1 7 555555
2 5 AAAAAA
 
Это то что надо ведь?
mae
8 - 06.06.2004 - 19:55
Совершенно верно! Сенкс!
Но я подозреваю, что каждый раз придётся ещё и удалять временную таблицу.
А вообще стоит ли овчинка выделки, если вся таблица занимает около 600 килобайт? Может быть не так накладно для ресурсов будет делать так, как сейчас у меня сделано - брать всю таблицу и средствами perl загонять её в массив и вытаскивать оттуда то, что нужно? Или всё-таки лучше делать 3 запроса - создание временной таблицы, select, удаление таблицы?
Уверенный
9 - 06.06.2004 - 23:54
Думаю, тесты производительности тебе помогут выбрать нужный способ. Кстати, описанный вариант в случае наличия двух "максимальных" записей выдаст обе. Ну их уже "отфильтровать" можно и в perl. :)

К списку вопросов на форуме Веб-дизайн

>>