MySql - антисортировка
2009-05-07 Вася
2009-05-06 Вася
2009-05-05 Петя
2009-05-04 Петя
2009-05-03 Коля
2009-05-02 Коля
2009-05-01 Коля
Нужно вывести таблицу отсортировав следующим образом. По дате - но для каждого имени по очереди. Не понимаю как это сказать по русски. Но выглядеть должно так.
2009-05-07 Вася
2009-05-05 Петя
2009-05-03 Коля
[COLOR=navy]2009-05-06 Вася[/COLOR]
[COLOR=navy]2009-05-04 Петя[/COLOR]
[COLOR=navy]2009-05-02 Коля[/COLOR]
2009-05-01 Коля
Сначала идут самые свежи датые для каждого имени, потом вторые, третьи и т.п.
Хочется сделать средствами MySql :) Возможно добавление дополнительных полей.
не?
не?
Нет, нужно сначала по самой свежей дате для каждого имени, потом по второй по свежести для каждого имени и т.п. А тут просто сортировка сначала по имени потом по дате.
В Oracle всё это можно сделать так. Допустим таблица называется TBL, а поля в ней: DT - дата, NAME - имя:
(select t1.dt, t1.name, count(*) as cnt
from tbl t1, tbl t2
where t1.name = t2.name and t1.dt < t2.dt
group by t1.name, t1.dt
union
select t1.dt, t1.name, 0 as cnt from tbl t1
where not exists (select * from tbl where name = t1.name and dt > t1.dt))
order by cnt, name
В MySql, думаю, тоже можно сделать что-то подобное.
Правда, при большом количестве записей в таблице запрос просядет, имхо.
t1.date,
t1.name,
COUNT(*) as cnt
from
@table t1
inner join @table t2 on (t1.date >= t2.date and t1.name = t2.name)
group by
t1.date,
t1.name
order by cnt,date
Upd.
Кстати может еще посмотреть в сторону расширения SQL для MySQL. Для примера на MS SQL можно было бы сделать так
t1.date,
t1.name
from
@table t1
order by
row_number() over (partition by t1.name order by t1.date),
t1.date
Но правда в MS SQL такая красота появилась только с версии 2005, так что не знаю есть ли что-то подобное у MySQL.
t1.date,
t1.name,
COUNT(*) as cnt
from
@table t1
inner join @table t2 on (t1.date >= t2.date and t1.name = t2.name)
group by
t1.date,
t1.name
order by cnt,date
Да, так безусловно проще, и в Oracle тоже работает.
Но здесь есть как минимум одна неточность.
Знак >= (в выражении t1.date >= t2.date) нужно заменить на <=. Иначе в COUNT(*) as cnt будет получено, сколько записей было с более ранней датой, чем текущая, что в итоге приведет к тому, что запрос для каждого name выведет по 1 записи с наиболее ранней датой, затем - по 1 более поздней и т.д. Судя по представленному mike примеру того, что нужно получить, ему нужно как раз наборот - сначала по 1 записи с наиболее поздними датами, потом - по 1 с более ранними, и т.д.
+ как мне кажется, в order by cnt, date нужно либо добавить desc после name, либо заменить date на name. Но могу и ошибаться...
2Romik: печально=)