2013-03-27 1 views
1

Je veux obtenir les îles de ce tableau ci-dessous:SQLite requête pour regrouper plage continue de numéros en groupe différents ensembles

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 

Je veux obtenir ce résultat en utilisant SQL (les îles):

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

J'ai vu beaucoup de codes/forums pour cela mais je ne travaille pas avec SQLite parce que SQLite n'a pas de CTE. 100-101 est continu, de sorte qu'il sera groupé en un.

Est-ce que quelqu'un sait comment le faire dans SQLite?

Répondre

1

Le moyen le plus rapide de le faire serait de parcourir les enregistrements ordonnés de cette table en boucle et de collecter les îlots manuellement.

En langage SQL pur (en tant que langage orienté ensemble), ce n'est pas si simple. En premier lieu, nous découvrons quels enregistrements sont les premiers dans une île. Le premier enregistrement ne dispose pas d'un précédent record, soit un record avec le même groupe mais avec un MemberNo un plus petit:

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) 

Pour trouver le dernier enregistrement d'une île, nous devons trouver le dossier avec le plus grand MemberNo qui appartient toujours à la même île, c'est à dire, a le même groupe, et où tous les MemberNo s dans l'île sont continus. Nous détectons MemberNo en continu en calculant la différence entre leurs valeurs dans le premier et le dernier enregistrement. La dernière MemberNo de l'île avec le groupe et G premier MemberNoM peut être calculé comme suit:

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) 

Enfin, brancher sur la première requête:

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) 
Questions connexes