2010-05-14 2 views
0

Возьмите этот простой запрос:GROUP BY даты, с упорядочением по дате

SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay
FROM someTable
GROUP BY formatterDay

Это будет выбирать строки из таблицы с только 1 ряд на сегодняшний день.
Как обеспечить, чтобы строка, выбранная для даты, была самой ранней для этой даты, без выполнения упорядоченного подзапроса в FROM?

Приветствие

ответ

1

Если вы используете MySQL, вы не сможете делать то, что хотите, в одном выборе. Вам понадобится внутренний запрос, который выбирает минимальный идентификатор и форматированное или другое поле для каждой форматированной даты. Затем снова присоедините его к родительской таблице и выберите записи с минимальным идентификатором.

В других базах данных (postgresql, oracle, db2) есть функции окон, которые позволяют сделать это в одном select (то есть DENSE_RANK() OVER ...).

Вот пример с внутренним запросом (который вы можете уже быть в курсе):

SELECT B.formattedDay, A.* 
    FROM someTable A 
     JOIN 
     (
      SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay, 
        MIN(ID) as firstId 
      FROM someTable I 
     GROUP BY 1 
     ) B ON (A.ID = B.firstId) 

Изменение MIN (ID) для MIN (someDate) при необходимости и его метку времени. Если может отображаться более одной записи с одинаковой временной меткой, вам необходимо выполнить операцию дважды. Сначала получают минимальную дату в день, затем минимальный ID за минимальную дату.

+0

Спасибо. Я смог сделать это с помощью внутреннего запроса, но задавался вопросом, есть ли способ сделать это без него. Вы ответили на этот вопрос. :) –

+0

Хотелось бы, я пропустил возможность генерировать плотный столбец рангов, а затем просто выбирать строки, где dense_rank равен 1. Ну ладно, по крайней мере, MySql быстр. Приветствия. – Gennadiy

0

Я бы переписать запрос так:

SELECT distinct DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay 
    FROM someTable 
ORDER BY DATE_FORMAT(someDate, '%y-%m-%d') 

Если вы абсолютно необходимы группа, (IE вы используете агрегатную функцию вы не показывая нам) просто сделать:

SELECT DATE_FORMAT(someDate, '%y-%m-%d') as formattedDay 
    FROM someTable 
GROUP BY DATE_FORMAT(someDate, '%y-%m-%d') 
ORDER BY DATE_FORMAT(someDate, '%y-%m-%d') -- this is redundant, but you can use another column here 
+0

Ни один из них не будет работать. Первое будет возвращать строки в одну и ту же дату (я хочу только одну строку на дату, следовательно, группу), а вторая не гарантирует, что будет выбрана самая ранняя дата для каждого дня. –

Смежные вопросы