代码之家  ›  专栏  ›  技术社区  ›  ahajib Shaun McHugh

仅在连续行上按SQL分组

  •  0
  • ahajib Shaun McHugh  · 技术社区  · 6 年前

    所以我有一张桌子,看起来像:

    SITE      LOWER   UPPER   SIZE
    a.com     0.1     0.2     10
    a.com     0.2     0.3     10
    a.com     0.3     0.4     10
    a.com     0.7     0.8     10
    a.com     0.9     1.0     10
    b.com     0.1     0.2     20
    a.com     0.6     0.7     30
    

    我期望的输出是:

    SITE      LOWER   UPPER   SIZE
    a.com     0.1     0.4     10
    a.com     0.7     1.0     10
    b.com     0.1     0.2     20
    a.com     0.6     0.7     30
    

    所以对于一个 SITE SIZE 对,我需要压缩 LOWER UPPER 值,其中 按行分组的是第一行和 鞋帮 是最后一行的最大值。 鞋帮 就像一些bucket的下限和上限值(例如[0.1,0.2]),我只需要连续的bucket压缩在一起。在这方面,任何帮助都将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Gordon Linoff    6 年前

    可以使用变量将组ID分配给相邻行:

    select t.*,
            (@grp := IF(@sru = CONCAT_WS(':', site, rev, lower), 
                        IF(@sru := CONCAT_WS(':', site, rev, upper), @grp, @grp),
                        IF(@sru := CONCAT_WS(':', site, rev, upper) , @grp + 1, @grp + 1)
                       )
                ) as grp
    from (select t.*
          from t
          order by site, size, lower
         ) cross join
         (select @grp := 0, @sru := '') params;
    

    然后您可以聚合以获得所需的内容:

    select site, size, min(lower) as lower, max(upper) as upper
    from (select t.*,
                 (@grp := IF(@sru = CONCAT_WS(':', site, rev, lower), 
                             IF(@sru := CONCAT_WS(':', site, rev, upper), @grp, @grp),
                             IF(@sru := CONCAT_WS(':', site, rev, upper) , @grp + 1, @grp + 1)
                            )
                 ) as grp
          from (select t.*
                from t
                order by site, size, lower
               ) cross join
               (select @grp := 0, @sru := '') params
         ) t
    group by size, size, grp;
    

    Here 是一个SQL助手。