2016-05-24 5 views
1

Hy, kleine Hilfe bitte, ich habe eine vollständige Sequenz von 12 Elemente, identifiziere ich diese Elemente von 2 verschiedenen Gruppen (12345 und 54321). Nun, ich brauche die erste Folge von der Position „12345“ bei 4 aufhören zu identifizieren und neu starten zu 10. So etwas:MYSQL: Finden Sie fehlende Werte in einer Sequenz von verschiedenen Gruppen

Ich habe diese Tabelle:

------------------ 
|seq |partNumber| 
------------------ 
| 1 | 12345 | 
| 2 | 12345 | 
| 3 | 12345 | 
| 4 | 12345 | 
| 10 | 12345 | 
| 11 | 12345 | 
| 12 | 12345 | 
| 5 | 54321 | 
| 6 | 54321 | 
| 7 | 54321 | 
| 8 | 54321 | 
| 9 | 54321 | 
------------------ 

Ich brauche dieses Ergebnis zu finden:

------------ 
|Start|Stop| 
------------ 
| 5 | 9 | (partnumber:12345) 
------------ 

die Abfrage, die ich verwendet:

select start, stop from (
select m.partNumber + 1 as start, 
    (select min(partNumber) - 1 from seq as x where x.partNumber > m.partNumber) as stop 
    from seq as m 
    left outer join seq as r on m.partNumber = r.partNumber - 1 where r.partNumber is null) as x 
where stop is not null; 

Aber diese Abfrage gibt mir dieses Ergebnis:

------------ 
|Start|Stop| 
------------ 
| 9 | 9 | (partnumber:12345) 
------------ 

Endergebnis: möchte ich Sequenz von „12345“ in 1 endet beginnt bei 10 in 4 (Pause) Neustart identifizieren Enden 12, ich habe einen Spalt in 5 bis 9. Die andere Sequenz von „54321 "beginnt an 5 Enden in 9, hier habe ich keine Lücke.

+0

schlug mich zu ihm, @ user42 –

+0

Können Sie in dieser Anwendung, weisen eine Obergrenze auf den Wert von 'seq'? –

+0

Mögliche Duplikate von [Wie Lücken in der fortlaufenden Nummerierung in MySQL zu finden?] (Http://stackoverflow.com/questions/4340793/how-to-find-gaps-in-sequential-numbering-in-mysql) – nada

Antwort

0

Dies ist eine gute Anwendung für die strukturierte Teil strukturierte Abfragesprache.

Ich denke, man wird nie 15624 einen Wert von seq kleiner als Null oder größer als der willkürlichen Wert hat. Diese Vermutung ist wichtig: Wir benötigen eine Tabelle mit allen Kardinalzahlen in diesem Bereich, um die Erkennung fehlender Zahlen zu ermöglichen.

Hier ist eine solche Tabelle

SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq 
    FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A 
    JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B 
    JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C 
    JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D 
    JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E 
    JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F 

(Wenn Sie MariaDB verwenden, können Sie die Sequence Tabelle seq_0_to_15624 anstelle dieser Klumpen von SQL-Code verwenden.)

Als nächstes müssen Sie eine So finden Sie den niedrigsten und höchsten Wert von seq für jede Teilenummer. Das machst du so.

 SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq 
     FROM seq 
     GROUP BY partNumber 

Als nächstes müssen Sie eine Tabelle erzeugen, alle möglichen Sequenznummern von Minimum bis Maximum für jede Teilenummer zeigt:

SELECT cardinals.seq, r.partNumber 
    FROM (
     SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq 
      FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A 
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F 
     ) cardinals 
    JOIN (
     SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq 
      FROM seq 
      GROUP BY partNumber 
    ) r ON cardinals.seq >= r.minSeq AND cardinals.seq <= r.maxSeq 

Schließlich können Sie LINKE, dass Original-Tabelle Ihr JOIN und tun WHERE val IS NULL, um Ihre fehlenden Sequenznummern zu finden.

SELECT cardinals.seq, r.partNumber 
    FROM (
     SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq 
      FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A 
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E 
     JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F 
      ) cardinals 
    JOIN (
      SELECT partNumber, MIN(seq) minSeq, MAX(seq) maxSeq 
       FROM seq 
       GROUP BY partNumber 
     ) r ON cardinals.seq >= r.minSeq AND cardinals.seq <= r.maxSeq 
    LEFT JOIN seq ON cardinals.seq = seq.seq AND r.PartNumber = seq.partNumber 
WHERE seq.seq IS NULL 
+0

Ok, das funktioniert. Danke Ollie, aber können wir sie gruppieren wie: Start - 5; Stop - 9? Ich werde versuchen – Gomez

+0

Finden Sie es: SELECT min (Kardinäle.seq) als START, SELECT max (cardinals.seq) als STOP, r.partNumber (...) Noch einmal, danke Ollie, rette meinen Tag. – Gomez

+0

Hallo, Ollie Jones, die Abfrage generiert ein ** NULL **: Ich habe Sequenz 7298 bis zu 7478 von einer Teilenummer, aber in der Mitte habe ich andere Teilenummer (die Reihenfolge dieser Teilenummer ist 7375 bis 7434) und diese Abfrage findet diese Lücke nicht. Angeblich wäre das Ergebnis 7298 - 7374 (eine Teilenummer); 7375 - 7434 (die andere Teilenummer) und schließlich 7435 - 7478 (die erste Teilenummer wieder). kannst du mir helfen? – Gomez

Verwandte Themen