Обнаружение кроссовера в MYSQL - PullRequest
0 голосов
/ 24 октября 2018

Если существует таблица MySQL, которая содержит три столбца, один из которых является датой, а два других - это количество 1 и количество 2. Я пытаюсь найти все даты, где кривая, построенная по количеству 1 против даты, пересекает количество 2Против даты?И проблема в том, что иногда данные могут не охватывать точки, где происходит кроссовер, в этом случае я должен найти даты вскоре после кроссовера. Есть ли способ, которым я могу сделать это в MySQL?

1 Ответ

0 голосов
/ 24 октября 2018

Во-первых, обратите внимание, что маркер пересечения двух кривых заключается в том, что на заданную дату выполняется одно из двух условий:

  • Первая кривая больше, чем вторая кривая, инепосредственно перед предыдущей датой вторая кривая была больше первой или
  • Обратное из вышеизложенного истинно

Учитывая, что у вас есть доступ к MySQL 8+, мыможно попробовать использовать аналитическую функцию LAG здесь:

WITH yourTable AS (
    SELECT '2018-01-01' AS date, 1 AS quantity1, 5 AS quantity2 UNION ALL
    SELECT '2018-01-02', 3, 4 UNION ALL
    SELECT '2018-01-03', 4, 3 UNION ALL
    SELECT '2018-01-04', 2, 5 UNION ALL
    SELECT '2018-01-05', 4, 7 UNION ALL
    SELECT '2018-01-06', 9, 8
),
cte AS (
    SELECT
        date, quantity1, quantity2,
        LAG(quantity1) OVER (ORDER BY date) AS q1lag,
        LAG(quantity2) OVER (ORDER BY date) AS q2lag
    FROM yourTable
)

SELECT
    date
FROM cte
WHERE
    (quantity1 > quantity2 AND q1lag < q2lag) OR
    (quantity2 > quantity1 AND q2lag < q1lag);

enter image description here

Вот диаграмма выборочных данных временного ряда:

enter image description here

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

Демонстрация

Обратите внимание, что при этом будет получено большее значение пары дат, в течение которых две диаграммы пересеклись.В общем случае между двумя датами должно происходить скрещивание.

Редактировать:

Если ваша версия MySQL более ранняя, чем 8+, то нам придется использовать другой способнайти LAG.Один из вариантов - использовать коррелированный подзапрос:

SELECT date
FROM
(
    SELECT
        date, quantity1, quantity2,
        (SELECT quantity1 FROM yourTable t2
         WHERE t2.date < t1.date ORDER BY t2.date DESC LIMIT 1) AS q1lag,
        (SELECT quantity2 FROM yourTable t2
         WHERE t2.date < t1.date ORDER BY t2.date DESC LIMIT 1) AS q2lag
   FROM yourTable t1
) t
WHERE
    (quantity1 > quantity2 AND q1lag < q2lag) OR
    (quantity2 > quantity1 AND q2lag < q1lag);

Демо

...