У меня есть таблица:
id timestamp
1 1
23 2
12 4
45 6
3 7
4 8
Мне нужен этот результат:
major minor
1 2
1 4
1 6
2 4
2 6
2 7
Мне нужно присоединиться к каждому номеру со следующими тремя наименьшими номерами. Поскольку эти числа вставляются не в порядок, я не могу использовать идентификаторы.
Поскольку числа также не являются регулярными интервалами, я не могу установить конкретный предел, чтобы найти максимальное число для соединения.
Решения, которые у меня есть:
Я мог бы создать временную таблицу и использовать для этого автоматический идентификатор увеличения.
Я могу сделать это для одного числа и написать сценарий для итерации по таблице. Это запрос для него (идя сейчас, пока не появится что-то лучше):
SELECT * FROM
(SELECT id major_id, timestamp major_timestamp FROM timestamps WHERE interval_id=7 ORDER BY timestamp DESC limit 1) timestamps_major
LEFT JOIN
(SELECT id minor_id, timestamp minor_timestamp FROM timestamps WHERE timestamp < (SELECT timestamp FROM timestamps WHERE interval_id=7 ORDER BY timestamp DESC limit 1) ORDER BY timestamp DESC LIMIT 2) timestamps_minor
ON major_timestamp>minor_timestamp
Это нужно сделать только для всех номеров один раз, а затем один раз в день для расчета и хранения скользящей средней. Так что скорость не проблема.
Подумайте, как лучше всего подойти к этому. Благодарю.
EDIT: Это фактическая таблица с метками времени и идентификаторами. Пример, который я опубликовал, просто упрощен ради вопроса.
CREATE TABLE 'timestamps' (
'id' mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
'interval_id' tinyint(3) unsigned NOT NULL,
'timestamp' int(10) unsigned NOT NULL,
PRIMARY KEY ('id'),
UNIQUE KEY 'interval_timestamp' ('interval_id','timestamp'),
KEY 'interval_id' ('interval_id'),
KEY 'timestamp' ('timestamp'),
CONSTRAINT 'timestamps_ibfk_1' FOREIGN KEY ('interval_id') REFERENCES 'intervals' ('id') ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=75157 DEFAULT CHARSET=latin1
Вот возможное решение (см. Этот sqlfiddle, чтобы поиграть с ним)
SELECT *
FROM mytable major inner join mytable minor
ON minor.timestamp > major.timestamp
WHERE (SELECT COUNT(*) FROM mytable m WHERE m.timestamp < minor.timestamp and m.timestamp > major.timestamp) < 3
ORDER BY major.timestamp, minor.timestamp
Я определенно не уверен, что это самое чистое решение (и я не делал ничего, чтобы справляться с "связями" для равных временных меток), но он делает то, что вы хотите, поэтому это может быть что-то, что можно свести к минимуму.
Все, что я делаю, это объединение таблиц, а затем подсчет количества строк "между" майором и несовершеннолетним, так что я не получаю слишком много.