Mysql: Lücken finden

tklustig

Erfahrenes Mitglied
Hallo,
folgendes sql-Script soll alle Lücken auspüren, die durch Löschvorgänge im PrimaryKey entstanden sind. Die maximale Anzahl an Datensätzen stimmt nämlich nicht mit dem höchsten PK-Eintrag überein. Leider haut das Script nicht hin. Weiß jemand Abhilfe?
SQL:
SELECT COUNT(tabelle2.id)+1 as POS, tabelle1.id as POS2
FROM id_stadt as tabelle1 LEFT JOIN id_stadt as tabelle2
ON POS2>tabelle2.id
GROUP BY POS2
ORDER BY POS2 ASC;
Ich bekomme folgende Fehlermeldung
Code:
Unbekanntes Tabellenfeld 'POS2' in on clause
 
Versuche mal tabelle1.id statt POS2 in der ON Clause. Anscheinend sind Aliasse in der Projektionen in der Tat noch nicht in der ON-Clause verfügbar. (Projektionen [SELECT …] und damit einhergehend Alias-Setzung wird konzeptionell sowieso erst am Ende vor oder nach dem ORDER BY ausgeführt.)
 
Hab ich bereits probiert. Das Script stürzt ab, soll heißen, der MySQL-Server meldet irgendwann ma' ein TimeOut..
 
Hi,

ich vermute, dass ihm das "ON tabelle1.id > tabelle2.id" zu schaffen macht. Hier hast du enorm grosse Datenmenden, dein ON ist nicht restriktiv genug. Hier wird ihm whsl der Arbeitsspeicher ausgehen, weshalb er zu swappen anfängt und somit in den Timeout läuft.

Versuche mal mit zusätzliche Filtern oder temporären Tabellen zu arbeiten.

Rein aus Interesse: Wie viele Datensätze befinden sich in den beiden Tabellen?

Grüsse,
BK
 
Wenn für deinen PK sowieso schon ein Index vorliegt, der eine sortierte Ausgabe unterstützt, dann würde ich eine iterative Lösung mit einer Clientsprache probieren:
SQL:
SELECT id FROM id_stadt ORDER BY ID
In der Clientsprache (JS, PHP, C++, was du eben nutzt) dann einfach iterativ einen Zähler hochzählen. Das ist eine O(N) Lösung, besser kannst du nicht werden. Insbesondere ist das SQL-Query auch geschenkt, wenn der Index existiert.

(Ich bin mir sicher, dass das Iterieren bestimmt auch irgendwie in SQL geht, aber ich vermute stark, dass du die Lösung schneller in einer anderen Sprache gebastelt bekommst.)
 
Geht in die gleiche Richtung. Ich habe mal ein Script geschrieben, um die erste nicht gebrauchte ID zu ermitteln: [SQL] First not used Id

Wenn man den Ansatz von NEXT_ID nimt, kann man daraus auch das folgende ienfache Script erstellen
SQL:
select 
	*,
	next_id - id - 1 as missing_count
from
	(
		select 
			t1.id,
			(select min(t2.id) from test t2 where t2.id > t1.id) as next_id
		from 
			test t1
) dat
where not id+1 = next_id
Testinhlat der Tabelle Test:
Code:
ID
--
1 
2 
4 
8
Und das Resultat der Abfrage:
Code:
id | next_id | missing_count
----------------------------
 2 |       4 |             1
 4 |       8 |             3
 
Zuletzt bearbeitet:
Hi,

ich vermute, dass ihm das "ON tabelle1.id > tabelle2.id" zu schaffen macht. Hier hast du enorm grosse Datenmenden, dein ON ist nicht restriktiv genug. Hier wird ihm whsl der Arbeitsspeicher ausgehen, weshalb er zu swappen anfängt und somit in den Timeout läuft.

Versuche mal mit zusätzliche Filtern oder temporären Tabellen zu arbeiten.

Rein aus Interesse: Wie viele Datensätze befinden sich in den beiden Tabellen?

Grüsse,
BK
3679
 
Geht in die gleiche Richtung. Ich habe mal ein Script geschrieben, um die erste nicht gebrauchte ID zu ermitteln: [SQL] First not used Id

Wenn man den Ansatz von NEXT_ID nimt, kann man daraus auch das folgende ienfache Script erstellen
SQL:
select
    *,
    next_id - id - 1 as missing_count
from
    (
        select
            t1.id,
            (select min(t2.id) from test t2 where t2.id > t1.id) as next_id
        from
            test t1
) dat
where not id+1 = next_id
Testinhlat der Tabelle Test:
Code:
ID
--
1
2
4
8
Und das Resultat der Abfrage:
Code:
id | next_id | missing_count
----------------------------
2 |       4 |             1
4 |       8 |             3

Folgendes Script läuft ebenfalls in einen Timeout rein, zumindest auf meinem RaspberryPi bei einer Tabelle mit >14000 Datensätzen. Auf meinem Hauptrechner mit 8 GByte RAM hingegen läuft es durch, wenngleich es relativ lange dauert, bis er das Ergebnis liefert
SQL:
select
    *,
    next_id - id - 1 as missing_count
from
    (
        select
            t1.id,
            (select min(t2.id) from test t2 where t2.id > t1.id) as next_id
        from
            test t1
) dat
where not id+1 = next_id

...
und folgendes Script liefert nur die erste Lücke, nicht alle:
SQL:
SELECT
    MIN(newIds.newId) AS firstNotUsedId
FROM
    -- jeweils die nächst höhere ID ermitteln
    (SELECT id + 1 AS newId FROM test) AS newIds
    -- und mit der Tabelle zurückverknüpfen
    LEFT JOIN (SELECT id FROM test ) AS ids
        ON newIds.newId = ids.id
WHERE
    ids.id IS NULL;

Trotzdem Danke ob deiner Hilfe. Dass der Pi relativ wenig RAM hat führt halt immer wieder zu Nachteilen....
Beispielsweise wird folgender jQuery-Request ebenfalls quälend langsam aufgebaut, zumindest unter lighttpd. Unter Apache(XAMPP) läuft der Code flüssig:
Javascript:
         function rotiere_pic(photo_aktuell) {
                var anzahl = $('#photos img').length;
                photo_aktuell = photo_aktuell % anzahl;

                $('#photos img').eq(photo_aktuell).fadeOut(function () {
                    $('#photos img').each(function (i) {
                        $(this).css(
                                'zIndex', ((anzahl - i) + photo_aktuell) % anzahl
                                );
                    });
                    $(this).show();
                    setTimeout(function () {
                        rotiere_pic(++photo_aktuell);
                    }, 750);
                });
            }
Dieser Thread kann als erfolgreich gelöst geschlossen werden
 
Zuletzt bearbeitet:
Offtopic:

Beispielsweise wird folgender jQuery-Request ebenfalls quälend langsam aufgebaut, zumindest unter lighttpd. Unter Apache(XAMPP) läuft der Code flüssig:
Ich sehe da keinen (HTTP-)Request. Lässt du den Pi die Seite nur ausliefern oder betrachtest du die Seite mit einem Browser auch auf dem Pi?
Wenn du Ersteres, sollte es nicht am Pi liegen, außer der Browser lädt die Bilder nicht direkt hintereinander, sondern on-demand beim ersten jeweiligen Einblenden aufgrund eines zIndex-Wechsels. Dann könntest du die Bilder im Voraus laden. (Dazu gibt es einige Möglichkeiten, einfach mal nach "prefetch images" googeln.)
 
Ich hoste die Seite nur auf meinem Pi. Das OS(LINUX) hat weder eine GUI noch einen Browser. Die Seite wird außerhalb des lokalen Netzwerkes über einen Browser geladen. Wenn es stimmt, was du sagst, woran könnte es dann liegen?? Die "prefetch images"-Option werde ich mir ma' anschauen....
 
Zurück