Как я могу отставать столбцы в MySQL?
Рассмотрим следующую таблицу:
SELECT id, value FROM table ORDER BY id ASC;
+-----+---------+
| id | value |
+-----+---------+
| 12 | 158 |
| 15 | 346 |
| 27 | 334 |
| 84 | 378 |
| 85 | 546 |
+-----+---------+
id
столбец автоматически увеличивается, но содержит пробелы. value
столбец числовой
Я хочу посмотреть на увеличение value
со временем, установив value
по отношению к value
двумя рядами выше. Это для ряда id=85
Я хочу установить value
ряда id=85
(546) по отношению к value
ряда id=27
(334). Значение, которое будет вычислено для строки id=85
следовательно, 546/334=1,63473.
Вот результат, которого я хочу достичь:
SELECT id, value, ...;
+-----+---------+---------------------+
| id | value | value/lag(value, 2) | (the syntax value/lag(value, 2) is made up)
+-----+---------+---------------------+
| 12 | 158 | NULL |
| 15 | 346 | NULL |
| 27 | 334 | 2.11392 | (334/158=2.11392)
| 84 | 378 | 1.09248 | (378/346=1.09248)
| 85 | 546 | 1.63473 | (546/334=1.63473)
+-----+---------+---------------------+
Как мне выполнить такое отставание в MySQL?
Обратите внимание, что id
столбец содержит пробелы, поэтому просто объединение в одной таблице с t1.id = t2.id - 2
не будет работать.
2 ответа
Вот решение, которое возвращает то, что вы хотите в MySQL
SET @a :=0;
SET @b :=2;
SELECT r.id, r.value, r.value/r2.value AS 'lag'
FROM
(SELECT if(@a, @a:=@a+1, @a:=1) as rownum, id, value FROM results) AS r
LEFT JOIN
(SELECT if(@b, @b:=@b+1, @b:=1) as rownum, id, value FROM results) AS r2
ON r.rownum = r2.rownum
MySQL 5.1 не любит самостоятельное объединение с подзапросом, поэтому вам приходится считать строки дважды, поэтому не так аккуратно или масштабируемо, как могло бы быть, но это делает определение лага простым.
Для читателей, которые используют Oracle вместо этого, это намного проще
SELECT id, value, value/lag(value, 2) over (order by id) as lag from results;
Поскольку существует только две строки между текущей и той, из которой вы хотите получить "исторические" данные, вы можете использовать переменные для временного хранения данных, используя что-то вроде:
set @oldid0=999999;
set @oldid1=999999;
set @oldid2=999999;
select @oldid0:=@oldid1,@oldid1:=@oldid2,@oldid2:=id, value/@oldid0 from table order by id asc;
Это очень неопрятное решение, но я думаю, оно подойдет. Может быть, есть какой-то способ предотвратить отображение переменных, я не стал вдаваться в подробности.