![]() |
![]() |
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. :) |