Очень сложная группировка по / уникальному / лимит по SQL-команде

Я даже не знаю, как это назвать:P, но...

У меня есть одна таблица, давайте назовем ее "загрузки"

id    owner    date
-----------------------------
0     foo      20100101120000
1     bar      20100101120300
2     foo      20100101120400
3     bar      20100101120600
..    ..       ..
6     foo      20100101120800

Теперь, когда я сделаю что-то вроде:

SELECT id FROM uploads ORDER BY date DESC

Это приведет к:

id    owner    date
-----------------------------
6     foo      20100101120800
..    ..       ..
3     bar      20100101120600
2     foo      20100101120400
1     bar      20100101120300
0     foo      20100101120000

Вопрос: Хорошо, но я хочу пойти еще дальше. Потому что теперь, когда вы строите временную шкалу (а я это сделал:P), вас "спамят" сообщения о том, что foo и bar что-то загрузили. Я хотел бы сгруппировать их и вернуть первый результат с ограничением по времени в поле даты "500".

Какая SQL-команда мне нужна, это приведет к:

id    owner    date
-----------------------------
6     foo      20100101120800
3     bar      20100101120600
0     foo      20100101120000

Затем, после этого, я могу выполнить вызов для каждой записи, чтобы получить ассоциативные записи в течение 5 минут (это пример для id=6):

SELECT id FROM uploads WHERE date>=20100101120800-500 ORDER BY date DESC

У кого-нибудь сейчас есть как сделать первый шаг? (поэтому ограничение / группировка результатов)

(Кстати. Я знаю, что когда я хочу использовать это, я должен конвертировать каждую дату (YmdHis=60) в Unix-время (=100), но мне не нужно, чтобы 5 минут были ровно 5 минутами, они могут быть на минуту меньше иногда...)

3 ответа

Решение

Я не совсем понимаю, какой результат вы пытаетесь получить, даже с вашими примерами. Возможно что-то с округлением и группировкой.

SELECT max(id) max_id,owner, (ROUND(date/500)*500) date_interval, max(date) date
FROM uploads GROUP BY date_interval,owner

Вы можете использовать FLOOR или CEILING вместо ROUND, в зависимости от того, что вы хотите.

Стандартный SQL не очень хорошо справляется с интервалами. Вам нужно будет самостоятельно объединить таблицу, чтобы сравнить даты разных кортежей. Таким образом, вы можете легко найти все пары кортежей, даты которых не превышают 500. Однако вы действительно хотите кластеризовать даты в наборах с интервалом не более 500- и это, насколько я знаю, вообще не может быть выражено в SQL.

То, что вы можете сделать, - это нечто очень похожее: разбить общий временной интервал на фиксированные диапазоны по 500 единиц, а затем кластеризовать все кортежи в таблице на основе интервала, в котором они находятся. Для этого вам сначала понадобится таблица или результат запроса с время начала интервалов; это можно создать с помощью SQL-запроса к вашей таблице и функции, которая либо "округляет" временную метку до времени начала своего интервала, либо вычисляет его порядковый номер интервала. Затем в качестве второго шага вы можете объединить таблицу с этим результатом, чтобы сгруппировать ее временные метки в соответствии с их соответствующим временем начала. Я не могу дать SQL, потому что он зависит от СУБД, и я, конечно, не могу сказать вам, является ли это наилучшим способом достижения того, чего вы хотите в вашей ситуации.

Использовать встроенный вид? например что-то вроде

SELECT u1.* 
FROM uploads u1,
(SELECT date 
    FROM uploads u2
    WHERE u2.owner='foo') datum_points
WHERE u1.date BETWEEN datum_points.date
    AND DATE_ADD(datum_points.date INTERVAL 5 MINUTES)

должен вернуть все сообщения, сделанные в течение 5 минут после 'foo' создания сообщения.

Другие вопросы по тегам