2010-07-16 5 views
1

J'ai donc une table de journal. Les lignes sont essentiellement comme suit:MySQL: SELECT si la ligne suivante n'est pas comme prévu

id function 
n init() 
n+1 check() 
n+2 done() 
... repeat 

Mais il y a des problèmes quand il est comme ça:

id function 
n init() 
n+1 check() 
n+2 done() 
n+3 check() <-- should be init! 
n+4 done() 

Comment puis-je trouver des lignes qui se produisent seulement dans INIT-> Check-> fait-> Check-> fait l'ordre contagieux? Fondamentalement, après row done(), il faut à nouveau check() pour être SELECTed.

Existe-t-il un moyen de le faire dans une requête (ou minimale)? Les performances ne sont pas un problème.

+0

Pouvez-vous fournir quelques exemples de données? Ma curiosité est si votre colonne d'ID se réinitialise, ou est un auto_increment ... –

+0

C'est auto_increment et l'échantillon que j'ai donné est à peu près tout. C'est un journal très simple, j'ai seulement omis les timestamps – syaz

Répondre

3
SELECT line2.* 
    FROM log line2 
     JOIN log line1 
     ON line2.id = line1.id + 1 
    WHERE line1.function = 'done()' 
    AND line2.function = 'check()' 

Je sais que vous avez dit la performance n'a pas été un problème, mais encore;)

+0

Nice ... en quelque sorte je me suis borné à penser en termes de 1 SELECT (sans jointures) seulement. Je pensais que vous pouvez faire quelque chose comme regex lookahead. = P – syaz

+2

@SyaZ Il n'y a rien de mal avec les jointures, vraiment, elles sont là pour être utiles, pas évitées. – ceteras

+0

+1 ceteras: totalement d'accord :) –

1

Utilisation:

SELECT l.* 
    FROM LOG l 
    WHERE l.function = 'check()' 
     AND EXISTS(SELECT NULL 
          FROM LOG t 
          WHERE t.function = 'done()' 
           AND t.id = l.id-1) 

... pour obtenir le contrôle() la ligne qui vient après un fait(), et apparenly doit être "init()" au lieu.

+0

Merci, la première fois que j'ai vu SELECT NULL utilisé. – syaz

Questions connexes