Очень сложная группировка по / уникальному / лимит по 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' создания сообщения.