SQLite Query将连续范围的数字分组到不同的分组集中

时间:2013-03-27 05:54:34

标签: sqlite

我想要获得下表中的岛屿:

Group    MemberNo
A           100
A           101
A           200
A           201
A           202
A           203
X           100
X           101
A           204
X           301
X           302
A           500
A           600

我希望使用SQL(岛屿)获得此结果:

Group  FromMemberNo      ToMemberNo
A             100             101
A             200             204
X             100             101
X             301             302
A             500             500
A             600             600

我见过很多代码/论坛,但没有使用SQLite,因为SQLite没有CTE。

100-101是连续的,因此它将被分组为一个。

有人知道如何在SQLite中做到这一点吗?

1 个答案:

答案 0 :(得分:1)

执行此操作的最快方法是在循环中浏览此表的有序记录并手动收集这些岛。

在纯SQL(作为面向集合的语言)中,这并不容易。

首先,我们找出哪个记录​​是岛上的第一个。第一条记录没有以前的记录,即具有相同组但但MemberNo小一条记录的记录:

SELECT "Group",
       MemberNo AS FromMemberNo
FROM ThisTable AS t1
WHERE NOT EXISTS (SELECT 1
                  FROM ThisTable AS t2
                  WHERE t2."Group" = t1."Group"
                    AND t2.MemberNo = t1.MemberNo - 1)

要查找岛屿的最后一条记录,我们必须找到仍然属于同一岛屿的最大MemberNo记录,即具有相同的组,并且所有MemberNo s在岛上是连续的。 我们通过计算第一个和最后一个记录中它们的值之间的差异来检测连续的MemberNo。 具有组MemberNo和第一个G MemberNo的岛屿的最后M可以这样计算:

SELECT MAX(MemberNo) AS LastMemberNo
FROM ThisTable AS t3
WHERE t3."Group" = G
  AND t3.MemberNo - M + 1 = (SELECT COUNT(*)
                             FROM ThisTable AS t4
                             WHERE t4."Group" = G
                               AND t4.MemberNo BETWEEN M AND t3.MemberNo)

最后,将其插入第一个查询:

SELECT "Group",
       MemberNo AS FromMemberNo,
       (SELECT MAX(MemberNo)
        FROM ThisTable AS t3
        WHERE t3."Group" = t1."Group"
          AND t3.MemberNo - t1.MemberNo + 1 = (SELECT COUNT(*)
                                               FROM ThisTable AS t4
                                               WHERE t4."Group" = t1."Group"
                                                 AND t4.MemberNo BETWEEN t1.MemberNo AND t3.MemberNo)
       ) AS LastMemberNo
FROM ThisTable AS t1
WHERE NOT EXISTS (SELECT 1
                  FROM ThisTable AS t2
                  WHERE t2."Group" = t1."Group"
                    AND t2.MemberNo = t1.MemberNo - 1)