我想要获得下表中的岛屿:
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中做到这一点吗?
答案 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)