Выборка записей с максимальным значением в MySQL
Выбираем записи с максимальным значением определенного поля.
На всякий случай - требуется получить не сами максимальные значения, а записи, в которых определенное поле равно максимальному.
Если поля всего два - сработает простой запрос:
id|date
select id, max(date) from table1;
При добавлении еще одного поля задача выбора записей с максимальным значением усложняется:
id|date|count
чтобы получить все записи с максимальной датой:
1) для MySQL версии 4.1 и выше можно сделать одним запросом:
select * from table1 where date in (select max(date) from table1)
2)Если версия ниже, то это надо делать в два запроса:
select @mxdate:=max(date) from table1;
select * from table1 where date=@mxdate;
id|date|count (id, date primary key) - next level
нужно вычислить count для каждого id с последней датой (с максимальным значением даты)
решение в один запрос рабочее, но нерациональное - на склейку и сравнение строк уходит неоправданно много времени
SELECT * FROM cms_catalog_goods_is_arc
WHERE CONCAT( date, id )
IN (SELECT concat( max( date ) , id ) FROM cms_catalog_goods_is_arc GROUP BY id )
Гораздо быстрей операция поиска строк с максимальным значением производится с использованием временных таблиц:
CREATE Temporary TABLE table2 (
`id` int(11) NOT NULL, `date` datetime NOT NULL, `cnt` int(11) NOT NULL,
PRIMARY KEY (`id`,`date`)
) ;
insert into table2 (id,date) select id, max(date) from table1 group by id;
update table2 t2, table1 t1 set t2.cnt=t1.cnt where t2.id=t1.id and t2.date=t1.date;
теперь в table2 все нужные нам записи.
ps. Довольно часто выполнить два простых запроса получается выгоднее, чем один сложный. http://www.samag.ru/art/07.2007/07.2007_02.html
pps В многих других СУБД (например, MS SQL, Oracle, PostgreSQL …) такого рода выборки решаются гораздо проще (с точки зрения пользователя БД) - достаточно одного незамудренного запроса. Что называется “в одну строчку” ..
В Oracle такого рода задача легко решается одним запросом. Причем, методов выбора строк с максимальным значением поля (даты в нашем случае) несколько. Часть из них приведена ниже (спасибо гостю SQL.ru с ником “Добрый Э - Эх” - http://sql.ru/forum/actualthread.aspx?tid=580229#5985168 )
1)
select *
from (
select t.*, row_number()
over(partition by num
order by dt desc) as rn
from <table_name> t
)
where rn = 1;
2)
select t1.*
from <table_name> t1
left join <table_name> t2
on t1.num = t2.num
and t1.dt < t2.dt
where t2.num is null;
3)
select *
from <table_name> t1
where (num, dt) in
(
select num, max(dt)
from <table_name>
group by num
);
4)
select t1.*
from <table_name> t1,
(
select num, max(dt) as dt
from <table_name>
group by num
) v
where t1.num = v.num
and t1.dt = v.dt;
5)
select t1.*
from <table_name> t1
where not exists(
select null
from <table_name> t0
where t1.num = t0.num
and t1.dt < t0.dt
);
6)
select t1.*
from <table_name> t1
where dt = (
select max(dt)
from <table_name> t0
where t1.num = t0.num
)
Метки: mysql
Привет всем!
Вчера нашел через гугл по запросу “разработка электроники на заказ цены”
Рекомендую!
Пока!
Огромное спасибо, Вы мне очень помогли, я искал именно выборку по определенному полю…