具有聚合最大价值的交叉连接

Cross join with aggregate greatest value

我有以下table,我们称它为Segments

-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1            | 4          | 20    |
| 4            | 8          | 60    |
| 8            | 10         | 20    |
| 10           | 1000000    | 0     |
-------------------------------------

我正在尝试将此 table 与其自身合并,以获得以下结果集:

-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1            | 4          | 20    |
| 1            | 8          | 60    |
| 1            | 10         | 60    |
| 1            | 1000000    | 60    |
| 4            | 8          | 60    |
| 4            | 10         | 60    |
| 4            | 1000000    | 60    |
| 8            | 10         | 20    |
| 8            | 1000000    | 20    |
| 10           | 1000000    | 0     |
-------------------------------------

基本上,我需要连接每一行,以及它后面的每一行,然后获取之前连接的每一行之间的值的 MAX()示例:如果我将第 1 行与第 3 行连接起来,我将需要所有这 3 行的 MAX(Value)

我已经完成的是以下查询:

SELECT s1.SegmentStart, s2.SegmentEnd, GREATEST(s1.Value, s2.Value) as Value FROM Segments s1 CROSS JOIN Segments s2 ON s1.SegmentStart < s2.SegmentEnd

此查询创建了一个与所需查询类似的 table,但值字段以下列方式混淆(我在 !! 不同的行之间做了标记):

-------------------------------------
| SegmentStart | SegmentEnd | Value |
-------------------------------------
| 1            | 4          | 20    |
| 1            | 8          | 60    |
| 1            | 10         | !20!  |
| 1            | 1000000    | !20!  |
| 4            | 8          | 60    |
| 4            | 10         | 60    |
| 4            | 1000000    | 60    |
| 8            | 10         | 20    |
| 8            | 1000000    | 20    |
| 10           | 1000000    | 0     |
-------------------------------------

问题出在 GREATEST() 函数上,因为它只比较正在连接的两行(开始-结束 1-4、8-10),而不是整个间隔(在本例中,这将是 3 行,开始结束的行是 1-4、4-8、8-10)

我应该如何修改这个查询,或者我应该使用什么查询,以获得我想要的结果?

可能有帮助的其他信息:原始 table 中的行始终根据 SegmentStart 排序,并且不能有重复值或缺失值。 xy 之间的每个间隔在 table 中只会出现一次,没有重叠,也没有任何间隙。

我正在使用 Maria DB 10.3.13

是这样的吗?

SELECT
      s1.SegmentStart
    , s2.SegmentEnd
    , MAX(s.Value) as Value 
FROM
    Segments s1
    INNER JOIN Segments s2 ON (
        s2.SegmentEnd > s1.SegmentStart
    )
    INNER JOIN Segments s ON (
            s.SegmentStart >= s1.SegmentStart
        AND s.SegmentEnd <= s2.SegmentEnd
    )
GROUP BY
      s1.SegmentStart
    , s2.SegmentEnd