Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Elegantes auslesen aller Werte eines Feldes (https://www.delphipraxis.net/73433-elegantes-auslesen-aller-werte-eines-feldes.html)

bernau 18. Jul 2006 00:57

Datenbank: ADS • Zugriff über: TAdsTable

Elegantes auslesen aller Werte eines Feldes
 
Hi,

folgende Problemstellung:

Ich habe eine Datenbank/Tabelle, auf die ich mit einer TTable zugreife. In dieser Tabelle gibt es ein Feld "Ort". Ich möchte alle Orte auslesen und in eine Stringlist kopieren. In der Stringlist sollen die ausgelesenen Orte jeweils einmal vorkommen.

Die einfachste Möglichkeit wäre nun eigendlich folgendes:

Delphi-Quellcode:
sl:=TStringlist.create;
sl.sorted:=true;
sl.duplicates:=dupignore;

DieTabelle.first;

while not DieTabelle.eof do
  begin
   sl.add(DieTabelle.fieldbyname('Ort').asstring);  
   DieTabelle.next;
  end;


etc.

Bei einer Tabelle, in der wenige Orte sehr oft vorkommen, ist dies allerding nicht die effizienteste vorgehensweise.

Beispiel: In der Tabellen kommen jeweils 2000 mal der Ort Köln, Hamburg und Berlin vor. Insgesamt besitzt die Tabelle somit 6000 Einträge. Als Ergebnis sollen letztendlich 3 Einträge herauskommen. Dazu werden im oberen Beispiel aber 6000 Zugriffe auf die Tabelle durchgeführt.


Da muss es doch eine bessere Lösung geben. Oder?

semo 18. Jul 2006 06:10

Re: Elegantes auslesen aller Werte eines Feldes
 
gibts es dazu nicht den "group by" befehl von sql? :-)

oder wenn du es dir umständlicher machen möchtest,
dann prüfst du vor dem einfügen in deine stringliste ob der neu einzufügende wert bereits vorhanden ist.
etwa so:
Delphi-Quellcode:
if sl.IndexOf(DieTabelle.fieldbyname('Ort').asstring)>-1 then
  sl.add(DieTabelle.fieldbyname('Ort').asstring);

mbamler 18. Jul 2006 06:18

Re: Elegantes auslesen aller Werte eines Feldes
 
Nimm doch statt einer TTable z.B. eine TQuery
und selectiere mit "distinct" ...

Gruß
Matthias

uwewo 18. Jul 2006 06:25

Re: Elegantes auslesen aller Werte eines Feldes
 
Hi,

bei MySQL würde ich es über DISTINCT machen

SQL-Code:
select DISTINCT(Ort) from Tabelle
Gibt jeden Ort nur einmal zurück
Ich denke einen ähnlichen Befehl sollte es auch bei deiner DB geben.

bernau 18. Jul 2006 23:34

Re: Elegantes auslesen aller Werte eines Feldes
 
Zitat:

Zitat von computer-glossar.de
oder wenn du es dir umständlicher machen möchtest,
dann prüfst du vor dem einfügen in deine stringliste ob der neu einzufügende wert bereits vorhanden ist.
etwa so:
Delphi-Quellcode:
if sl.IndexOf(DieTabelle.fieldbyname('Ort').asstring)>-1 then
  sl.add(DieTabelle.fieldbyname('Ort').asstring);

Hi,

das brauche ich eigendlich nicht zu prüfen, da mit "sl.duplicates=dupignore" automatisch beim Einfügen der doppelte Eintrag ignoriert wird.

Eigendlich ging es mir darum, mit so wenig wie möglichen Zugriffen auf die Tabelle alle vorhandenen Orte herauszufiltern.


Viele Grüße

Gerd

Union 18. Jul 2006 23:36

Re: Elegantes auslesen aller Werte eines Feldes
 
Dann nimm den Vorschlag mit distinct - der ADS optimiert dann die Tabellenzugriffe. Sinnvoll wäre es, wenn Du auf das Feld "Ort" auch einen Index hast.

bernau 18. Jul 2006 23:44

Re: Elegantes auslesen aller Werte eines Feldes
 
An alle mit dem Hinweis auf SQL und Distinct.

Danke erst mal für die Antworten.

Aber...... Mich interessiert auch das Hintergrundwissen. Ist eben ein Sport für mich, Problemstellungen selber zu lösen bzw. zu begreifen und nicht auf vorhandenes in Form einer "Black Box" zurückzugreifen. Daher ist die Verwendung von TTable für mich Voraussetung.




Viele Grüße

Gerd

Union 18. Jul 2006 23:52

Re: Elegantes auslesen aller Werte eines Feldes
 
Dann könntest Du ja, wenn es um Tabellenoptimierung geht, auch folgende Vorgehensweise verwenden:
  • Index auf Ort erstellen
  • An den Anfang der Tabelle gehen
  • Merken des Ortes in String
  • Gesamte Tabelle durchlaufen
  • Vergleichen ob der Ort vom gemerkten Ort abweicht
  • Wenn ja, in die Stringliste schreiben und Ort erneut in String merken
Dabei wird aber immer die gesamte Tabelle durchlaufen. Wenn Du Deine DB-Struktur normalisierst, hättest Du dagegen sowieso jeden Ort nur einmal. Dann würde nicht mehr die Adresstabelle durchlaufen, sondern nur noch die Ortstabelle. Diese enthält dann jeden Ort nur einmal.

Oder Du bastelst Dir einen intelligenten Suchalgorithmus, der auf den jeweils nächsten Ort springt (z.B. durch Erhöhen der ASCII-Werte des aktuellen Ortes und anschliessendem Locate).

bernau 20. Jul 2006 23:38

Re: Elegantes auslesen aller Werte eines Feldes
 
Zitat:

Zitat von Union
Dann könntest Du ja, wenn es um Tabellenoptimierung geht, auch folgende Vorgehensweise verwenden:
  • Index auf Ort erstellen
  • An den Anfang der Tabelle gehen
  • Merken des Ortes in String
  • Gesamte Tabelle durchlaufen
  • Vergleichen ob der Ort vom gemerkten Ort abweicht
  • Wenn ja, in die Stringliste schreiben und Ort erneut in String merken
Dabei wird aber immer die gesamte Tabelle durchlaufen.

Das war ja im Grunde mein erster Ansatz. Der Funktioniert zwar, aber es soll eben nicht jeder Datensatz ausgelesen werden.


Zitat:

Zitat von Union
Oder Du bastelst Dir einen intelligenten Suchalgorithmus, der auf den jeweils nächsten Ort springt (z.B. durch Erhöhen der ASCII-Werte des aktuellen Ortes und anschliessendem Locate).

In diese Richtung wird's gehen. Das mit dem Erhöhen des ASCII-Wertes ist denke ich mal eine gute Sache.

Michael Habbe 21. Jul 2006 01:12

Re: Elegantes auslesen aller Werte eines Feldes
 
:gruebel: Warum nur so umständlich? Nimm ne TAdsQuery und sage dem SQL
SQL-Code:
select distinct Ort from Postleitzahlen order by Ort
und dann rein in die StringList
Delphi-Quellcode:
AdsQuery.SQL.Text := 'select distinct Ort from Postleitzahlen order by Ort';
AdsQuery.Open;
AdsQuery.First;
while not AdsQuery.Eof do
begin
  SL.Add(AdsQuery.FieldByName('Ort').AsString);
  AdsQuery.Next;
end;
AdsQuery.Close;


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:09 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz