Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

MySql - антисортировка

4
02 октября 2009 года
mike
3.7K / / 01.10.2002
Есть талица

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 :) Возможно добавление дополнительных полей.
2
02 октября 2009 года
squirL
5.6K / / 13.08.2003
select date,name from table order by name,date
не?
4
02 октября 2009 года
mike
3.7K / / 01.10.2002
Цитата: squirL
select date,name from table order by name,date
не?


Нет, нужно сначала по самой свежей дате для каждого имени, потом по второй по свежести для каждого имени и т.п. А тут просто сортировка сначала по имени потом по дате.

12K
02 октября 2009 года
Ghox
297 / / 26.07.2009
Если я правильно понял задачу mike, то один из вариантов такой может быть. В запросе использовать псевдостолбец, который для каждой записи таблицы будет содержать количество других записей таблицы с тем же именем, но с более поздней датой (т.е. сколько для каждой записи есть более "свежих" по отношению к ней записей для этого же имени). И провести сортировку по этому столбцу, и по имени пользователя.

В Oracle всё это можно сделать так. Допустим таблица называется TBL, а поля в ней: DT - дата, NAME - имя:
 
Код:
select * from
    (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, думаю, тоже можно сделать что-то подобное.
Правда, при большом количестве записей в таблице запрос просядет, имхо.
385
02 октября 2009 года
SomewherSomehow
477 / / 25.07.2004
Не совсем правильные результаты выдает запрос приведенный выше, я бы упростил его немного, но идея такая же...
Код:
select
    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 можно было бы сделать так
 
Код:
select
    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.
12K
02 октября 2009 года
Ghox
297 / / 26.07.2009
Цитата: SomewherSomehow
Не совсем правильные результаты выдает запрос приведенный выше, я бы упростил его немного, но идея такая же...
Код:
select
    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. Но могу и ошибаться...

285
02 октября 2009 года
Romik
479 / / 24.11.2002
в mysql нет оконных функций (over ())
385
02 октября 2009 года
SomewherSomehow
477 / / 25.07.2004
2Ghox: Да, если по убыванию то конечно, мой вариант выводит по возрастанию. В оракл конечно будет работать и в любой субд т.к. не выходит за рамки стандарта SQL.
2Romik: печально=)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог