SQL - HSQL 如何计算一个数字的连续出现次数

Posted

技术标签:

【中文标题】SQL - HSQL 如何计算一个数字的连续出现次数【英文标题】:SQL - HSQL How to count consecutive occurences of a number 【发布时间】:2013-06-30 12:34:07 【问题描述】:

我有这张桌子:

code |  Seq  | incr | Bin
------------------------
AQ   |  2701 |  1   | 1  
AQ   |  2702 |  2   | 0  
AQ   |  2703 |  3   | 1  
AQ   |  2704 |  4   | 1  
AQ   |  2705 |  5   | 1  
AQ   |  2706 |  6   | 1  
AQ   |  2707 |  7   | 1  
AQ   |  2708 |  8   | 0  
AQ   |  2709 |  9   | 1  
AQ   |  2710 | 10   | 1  
AQ   |  2711 | 11   | 0  
AQ   |  2712 | 12   | 1  

我需要获得连续“1”的最大计数以及结果计数的“Seq”列中第一行和最后一行的值。即:对于书面简化表,最大计数为'5',从“Seq” = 2703 开始​​,以“Seq” = 2707 结束

所以我想要一个应该是这样的结果表:

code |  SeqStart  | SeqEnd | Count
----------------------------------
AQ   |    2703    |  2707  |   5  
AR   |    2712    |  2722  |  11  

试图解决这个问题,我认为

"incr" - ("Bin" = 0 且最大 "incr" 但 从 3 到 7 的“incr”是 2,从 9 到 7 的“incr”是 8 10)

这可能是一个很好的数学方法,但是(因为我在这里写)我找不到为每行减法的正确第二个数字编写工作代码的方法

不幸的是,因为我使用的是 OpenOffice (3.4.1),所以我被困在 HSQLDB 1.8 上 如果有人可以帮助我,我将不胜感激,感谢阅读

【问题讨论】:

您可以将 HSQLDB 2.x 用作带有 OO 的外部数据库。此版本允许您在 SQL 中编写函数来执行任务。 【参考方案1】:

我自己只使用 hsql 1.8 找到了解决方案 - 如果其他人可能对此感兴趣,我将发布它:

SELECT "a"."code", ("a"."Seq"-"b"."MaxNum" +1) AS "SeqStart", "a"."Seq" AS "SeqEnd", "b"."MaxNum" AS "Count" 
FROM 
    (SELECT DISTINCT "x"."code", "x"."Seq", "x"."incr", "x"."Bin", "y"."incr1", CASE WHEN "x"."Bin" = 1 THEN ("x"."incr"-"y"."incr1") ELSE '0' END AS "Num" 
    FROM "MyTable" AS "x" 
    LEFT JOIN 
    (SELECT "code", "incr", MAX("incr1") AS "incr1" 
    FROM 
        (SELECT "a"."code", "a"."incr", "b"."incr" AS "incr1" 
        FROM "MyTable" AS "a", "MyTable" AS "b" 
        WHERE ("b"."incr" BETWEEN '1' AND ("a"."incr" -1)) AND "b"."Bin" = 0) 
    GROUP BY "code", "incr") AS "y" 
    ON "y"."code" = "x"."code" AND "y"."incr" = "x"."incr") AS "a" 
INNER JOIN 
    (SELECT "code", MAX("Num") AS "MaxNum" 
    FROM 
        (SELECT DISTINCT "x"."code", "x"."Seq", "x"."incr", "x"."Bin", "y"."incr1", CASE WHEN "x"."Bin" = 1 THEN ("x"."incr"-"y"."incr1") ELSE '0' END AS "Num" 
        FROM "MyTable" AS "x" 
        LEFT JOIN 
        (SELECT "code", "incr", MAX("incr1") AS "incr1" 
        FROM 
            (SELECT "a"."code", "a"."incr", "b"."incr" AS "incr1" 
            FROM "MyTable" AS "a", "MyTable" AS "b" 
            WHERE ("b"."incr" BETWEEN '1' AND ("a"."incr" -1)) AND "b"."Bin" = 0) 
        GROUP BY "code", "incr") AS "y" 
        ON "y"."code" = "x"."code" AND "y"."incr" = "x"."incr") 
    GROUP BY "code") AS "b" 
ON "b"."code" = "a"."code" AND "b"."MaxNum" = "a"."Num"

【讨论】:

【参考方案2】:

我只想添加上面查询的调优版本,速度快 15 倍:

SELECT "a"."code", ("a"."Seq"-"b"."MaxNum" +1) AS "SeqStart", "a"."Seq" AS "SeqEnd", "b"."MaxNum" AS "Count" 
FROM 
   (SELECT DISTINCT "x"."code", "x"."Seq", "x"."incr", "x"."Bin", "y"."incr1", CASE WHEN "x"."Bin" = 1 THEN ("x"."incr"-"y"."incr1") ELSE '0' END AS "Num" 
   FROM 
      "MyTable" AS "x" 
   LEFT JOIN 
      (SELECT "code", "incr", MAX("incr1") AS "incr1" 
      FROM 
         (SELECT "a"."code", "a"."incr", "b"."incr" AS "incr1" 
         FROM 
            "MyTable" AS "a" 
         INNER JOIN 
            ( SELECT "code", "incr", "Bin" 
            FROM 
               "MyTable" 
            WHERE "Bin" = 0 ) AS "b" 
         ON "b"."code" = "a"."code" AND ( "b"."incr" BETWEEN '1' AND ( "a"."incr" - 1 ) ) ) 
      GROUP BY "code", "incr") AS "y" 
   ON "y"."code" = "x"."code" AND "y"."incr" = "x"."incr") AS "a" 
INNER JOIN 
   (SELECT "code", MAX("Num") AS "MaxNum" 
   FROM 
      (SELECT DISTINCT "x"."code", "x"."Seq", "x"."incr", "x"."Bin", "y"."incr1", CASE WHEN "x"."Bin" = 1 THEN ("x"."incr"-"y"."incr1") ELSE '0' END AS "Num" 
      FROM 
         "MyTable" AS "x" 
      LEFT JOIN 
      (SELECT "code", "incr", MAX("incr1") AS "incr1" 
      FROM 
         (SELECT "a"."code", "a"."incr", "b"."incr" AS "incr1" 
         FROM 
            "MyTable" AS "a" 
         INNER JOIN 
            ( SELECT "code", "incr", "Bin" 
            FROM 
               "MyTable" 
            WHERE "Bin" = 0 ) AS "b" 
         ON "b"."code" = "a"."code" AND ( "b"."incr" BETWEEN '1' AND ( "a"."incr" - 1 ) ) ) 
      GROUP BY "code", "incr") AS "y" 
   ON "y"."code" = "x"."code" AND "y"."incr" = "x"."incr") 
GROUP BY "code") AS "b" 
ON "b"."code" = "a"."code" AND "b"."MaxNum" = "a"."Num"

【讨论】:

以上是关于SQL - HSQL 如何计算一个数字的连续出现次数的主要内容,如果未能解决你的问题,请参考以下文章

用SQL计算同一个字符(汉字、字母、数字、表情、符号)连续重复出现的次数

Teradata SQL:计算错误代码连续出现的次数(并在不发生时重置)

sql 180. 连续出现的数字

如何计算Dataframe中,列中元素连续出现次数

二十:数字重复长度计算

SQL查找连续出现的数字