MySQL - объединить строку со следующими N меньшими строками

0

У меня есть таблица:

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

Мне нужно присоединиться к каждому номеру со следующими тремя наименьшими номерами. Поскольку эти числа вставляются не в порядок, я не могу использовать идентификаторы.

Поскольку числа также не являются регулярными интервалами, я не могу установить конкретный предел, чтобы найти максимальное число для соединения.

Решения, которые у меня есть:

  1. Я мог бы создать временную таблицу и использовать для этого автоматический идентификатор увеличения.

  2. Я могу сделать это для одного числа и написать сценарий для итерации по таблице. Это запрос для него (идя сейчас, пока не появится что-то лучше):

    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
Теги:

1 ответ

1
Лучший ответ

Вот возможное решение (см. Этот 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

Я определенно не уверен, что это самое чистое решение (и я не делал ничего, чтобы справляться с "связями" для равных временных меток), но он делает то, что вы хотите, поэтому это может быть что-то, что можно свести к минимуму.

Все, что я делаю, это объединение таблиц, а затем подсчет количества строк "между" майором и несовершеннолетним, так что я не получаю слишком много.

  • 0
    Это очень хорошо! Я никогда не думал ставить счет внутри где. Мне потребовалось немного, чтобы понять логику, но это здорово. Большое спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню