Ich habe keinen 'Plan' für folgende Abfrage

Datenbanklösungen mit AOO/LO

Moderator: Moderatoren

Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Stephan »

Hallo,

in einer Tabelle (Name "Bestellungen") gibt es eine Spalte "Ident". In dieser Spalte können alle Ganzzahlen von 1 bis 30.000 vorkommen.

Gesucht ist ein SQL für: finde die niedrigsten 50 Zahlen (der 'Zahlenmenge' von 1 bis 30.000) die in "Ident" nicht vorhanden sind.

Das Abfrageergebnis muss quasi(*) nur die eine Spalte zurückliefern, ich brauche die 50 Zahlen letztlich als Listeneinträge für ein Kombinationsfeld.

(*)
ich schreibe "quasi" weil ja das Ergebnis ja Werte umfasst die gerade nicht in der Tabelle stehen



Gruß
Stephan
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Hiker »

Hallo,

Wenn Du nicht zu fein bist eine Hilfstabelle mit einer Spalte und den Werten von 1 bis 30000 z.B. aus Calc zu kopieren könntest Du folgenden Join verwenden:

Link:
https://www.tutorials.de/threads/select ... nd.358466/

Code: Alles auswählen

SELECT T1.Field1, T2.Field1
FROM T1 LEFT JOIN T2 ON T1.Field1 = T2.Field1
WHERE T2.Field1 Is Null;
dann noch sortieren und LIMIT 50

Mfg, Jörn
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Stephan »

Danke, aber das wollte ich vermeiden. Ich hatte bereits das hier gefunden:
http://www.donkarl.com/?FAQ3.16

und hoffte es ginge ohne zweite Tabelle. Ich habe nur keine Ahnung wie ich diese 30000 Zahlen schreiben soll, denn ich kenne nur die Schreibweise wo man alle Zahlen angibt, also {1,2,3,4 ...} und aber nichts wie (hypotetisch) {1-30000}.


Gruß
Stephan
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Hiker »

Hallo,

hört sich für mich so an, als suchst Du eine FOR-Schleife in SQL, das aber deklarativ statt prozedural ist.

Deinen Ansatz würde ich als Macro schreiben, ist aber wahrscheinlich langsam.

Für die Zahlengenerierung gibt es diverse Ansätze, eine Recht portable wäre diese:
https://www.experts-exchange.com/articl ... ation.html

Andere nutzen spezielle Datenbanktabellen wie DUAL und dann deren RowId und es gibt auch Sequenz-Generatoren, aber ob HSQL das hat, weiss ich nicht.

Bist Du bei HSQL oder Firebird oder bei einem anderen SQL-Dialekt?

Mfg, Jörn
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Hiker »

... bei Sqlite gibt es beispielsweise
https://www.sqlite.org/series.html

Mfg, Jörn
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Stephan »

Deinen Ansatz würde ich als Macro schreiben, ist aber wahrscheinlich langsam.
Genauso ist es, denn als Makro bereitet mir das keine Probleme, nur die Geschwindigkeit wird nicht reichen. Da es im Grunde schneller als mindestens 0,3 Sekunden sein sollte, habe ich das nicht einmal probiert, denn ich bin sicher es ist erheblich langsamer.

(0.3 Sekunden weil das in Praxis nach meiner Erfahrung/Empfinden der Wert ist wo der Anwender noch nicht das Gefühl des Wartens hat, obwohl eigentlich schon 0,3 SEkunden zu merken sind, und ich muss aber die Berechnung bei jedem Datensatzwechsel (im Formular) neu durchführen. OK, strenggenommen nur wenn ich von einem gerade neu angelegten Datensatz zu einem Bestehenden wechsele, aber da dieser Fall ja einer aller vorkommenden Fälle ist, hilft es mir letztlich nicht wenn die anderen Fälle schnell genug wären, weil ich dort auf die Neuberechnung verzichte)
Bist Du bei HSQL oder Firebird oder bei einem anderen SQL-Dialekt?
HSQL


Gruß
Stephan
RobertG
********
Beiträge: 2033
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von RobertG »

Hallo Stephan,

die Zahlenfolge bekommst Du über eine Tabelle geregelt, die tatsächlich die Anzahl von erforderlichen Datensätzen hat:

Code: Alles auswählen

SELECT (SELECT COUNT("ID")+1 FROM "ID_Leer" WHERE "ID" <= "a"."ID") AS "CID" FROM "ID_Leer" AS "a"
Die Tabelle hier heißt "ID_Leer".
Der folgende Code zeigt alle freien Stellen in "ID_Leer" - aber eben maximal bis zu der Anzahl an Datensätzen in dieser Tabelle.

Code: Alles auswählen

SELECT "x"."CID" FROM 
(SELECT (SELECT COUNT("ID")+1 FROM "ID_Leer" WHERE "ID" <= "a"."ID") AS "CID" FROM "ID_Leer" AS "a") AS "x" 
LEFT JOIN "ID_Leer" 
ON "x"."CID" = "ID_Leer"."ID" WHERE "ID_Leer"."ID" IS NULL
Hast Du irgendwo eine Tabelle parat, die die erforderliche Anzahl an Datensätzen hat, so kannst Du dort die Zahlenreihe mit dem Counter abfragen. Ansonsten zeigt Dir Dein Listenfeld nur die Treffer im unteren Bereich an und muss entsprechend aktualisiert werden, um auch Leerstellen weiter oberhalb zu finden.

Gruß

Robert
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Stephan »

Hallo Jörn,
Hallo Robert,

Danke für die Hilfe.

ich werde mich dann der Notwendigkeit beugen eine zweite Tabelle verwenden zu müssen.


Gruß
Stephan
F3K Total
********
Beiträge: 3704
Registriert: Mo, 28.02.2011 17:49

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von F3K Total »

Hallo Stephan,
wenn du eine interne HSQLDB verwendest, und folgende Abfrage in "Direktem SQL MODE" ausführst, solltest du ohne Zusatztabelle auskommen:

Code: Alles auswählen

SELECT "Z" MISSING_NUMBERS FROM 
    (SELECT DISTINCT
         cast(A.Z||B.Z||C.Z||D.Z||E.Z as INTEGER) AS Z
     FROM
        (SELECT "ORDINAL_POSITION" -1 Z FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" WHERE "TABLE_NAME" = 'SYSTEM_PROCEDURES') A ,
        (SELECT "ORDINAL_POSITION" -1 Z FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" WHERE "TABLE_NAME" = 'SYSTEM_PROCEDURES') B ,
        (SELECT "ORDINAL_POSITION" -1 Z FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" WHERE "TABLE_NAME" = 'SYSTEM_PROCEDURES') C ,
        (SELECT "ORDINAL_POSITION" -1 Z FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" WHERE "TABLE_NAME" = 'SYSTEM_PROCEDURES') D ,
        (SELECT "ORDINAL_POSITION" -1 Z FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" WHERE "TABLE_NAME" = 'SYSTEM_PROCEDURES') E WHERE Z <=30000)AS "Z"
WHERE 
    "Z" not in (SELECT DISTINCT "Ident" FROM "Bestellungen")
ORDER BY MISSING_NUMBERS LIMIT 50 offset 0
Gruß Rik
Hiker
******
Beiträge: 590
Registriert: Mo, 08.09.2014 21:34
Wohnort: Berlin

Re: Ich habe keinen 'Plan' für folgende Abfrage

Beitrag von Hiker »

Hallo,

gogo hat hier https://www.libreoffice-forum.de/viewto ... 10&t=33392
einen ebenfalls recht interessanten Ansatz, wenn man nicht unbedingt alle fehlenden, sondern nur "Löcher" finden will.

Code: Alles auswählen

select * from t_platten p where not exists (select 1 from t_platten e where p.ID_PLATTE = (e.ID_PLATTE - 1))
Wenn man das noch mit LIMIT 1 kürzt, weiss man wo man einfügen kann...

Mfg, Jörn
Libre Office 6.3.1 (Win 10 Pro) / Libre Office 6.0.7 (Win8.1 Pro, Win 7 Pro) / AOO (Win 7)
Antworten