MYSQL中的交叉检测

时间:2018-10-24 08:04:58

标签: mysql relational-database mysql-workbench

如果有一个MySQL表,其中包含三列,一个是日期,另外两个是数量1和数量2。我试图找到所有日期,其中数量1对日期绘制的曲线与数量2相交对日期?而且问题是有时数据可能不包含发生交叉的点,在这种情况下,我应该在交叉之后立即找到日期。在MySQL中有什么方法可以做到这一点?

1 个答案:

答案 0 :(得分:1)

首先,请注意两条曲线交叉的标记是在给定的日期,两个条件之一为真:

  • 第一条曲线大于第二条曲线,并且在紧接的前一天,第二条曲线大于第一条曲线,或者
  • 上面的相反是真的

鉴于您可以使用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

应该清楚,在结果集中的三个日期中的每个日期,两个时间序列与前一个日期相比都相互交叉。

Demo

请注意,这将产生两个图表相交的一对日期中较大的值。通常,交叉发生在两个日期之间。

编辑:

如果您的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);

Demo