Подтвердить что ты не робот

Имитировать функцию задержки в MySQL

| time                | company | quote |
+---------------------+---------+-------+
| 0000-00-00 00:00:00 | GOOGLE  |    40 |
| 2012-07-02 21:28:05 | GOOGLE  |    60 |
| 2012-07-02 21:28:51 | SAP     |    60 |
| 2012-07-02 21:29:05 | SAP     |    20 |

Как сделать задержку в этой таблице в MySQL для печати разницы в кавычках, например:

GOOGLE | 20
SAP    | 40  
4b9b3361

Ответ 1

Это мой любимый взлом MySQL.

Вот как вы эмулируете функцию задержки:

SET @quot=-1;
select time,company,@quot lag_quote, @quot:=quote curr_quote
  from stocks order by company,time;
  • lag_quote содержит значение предыдущей строки. Для первой строки @quot -1.
  • curr_quote содержит значение текущей строки.

Примечания:

  • order by важно здесь, как и в обычном оконная функция.
  • Вы также можете использовать lag для company, чтобы быть уверенным, что вы вычисляете разницу в кавычках одного и того же company.
  • Вы также можете реализовать счетчики строк таким же образом @cnt:[email protected]+1

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

ИЗМЕНИТЬ:

Теперь приступим к вашему вопросу получения результата в указанном вами формате:

SET @quot=0,@latest=0,company='';
select B.* from (
select A.time,A.change,IF(@comp<>A.company,1,0) as LATEST,@comp:=A.company as company from (
select time,company,[email protected] as change, @quot:=quote curr_quote
from stocks order by company,time) A
order by company,time desc) B where B.LATEST=1;

Вложения не связаны друг с другом, поэтому не так плохо (вычислительно), как выглядит (синтаксически):)

Сообщите мне, нужна ли вам помощь.

Ответ 2

Из MySQL 8.0 и выше нет необходимости моделировать LAG. Он поддерживается,

Функция окна:

Возвращает значение expr из строки, которая отстает (предшествует) текущей строке на N строк в своем разделе. Если такой строки нет, возвращаемое значение будет по умолчанию. Например, если N равно 3, возвращаемое значение является значением по умолчанию для первых двух строк. Если N или значение по умолчанию отсутствует, значения по умолчанию равны 1 и NULL соответственно.

SELECT
     company,
     quote,
     LAG(quote) OVER(PARTITION BY company ORDER BY time) AS prev_quote
FROM tab;

Демоверсия DBFiddle

Ответ 3

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

SELECT c.company, c.mts, max(l.ts) AS lts
  FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c
  LEFT JOIN cq l
    ON c.company = l.company AND c.mts > l.ts
 GROUP BY c.company, c.mts;

Теперь вам нужно присоединиться к этому подзапросу с исходной таблицей, чтобы получить желаемые результаты:

SELECT c.company, l.quote, coalesce(l1.quote, 0),
       (l.quote - coalesce(l1.quote, 0)) AS result
  FROM (SELECT c.company, c.mts, max(l.ts) AS lts
      FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c
      LEFT JOIN cq l
        ON c.company = l.company AND c.mts > l.ts
     GROUP BY c.company, c.mts) AS c
  LEFT JOIN cq AS l ON l.company = c.company AND l.ts = c.mts
  LEFT JOIN cq AS l1 ON l1.company = c.company AND l1.ts = c.lts;

Вы можете увидеть результаты SQL Fiddle.

Этот запрос использует только стандартные возможности SQL и должен работать на любой РСУБД.