Entwickler-Ecke

Datenbanken - Schleifen und Zählproblem


valherf - Do 10.02.11 18:26
Titel: Schleifen und Zählproblem
hallo...
Habe ein recht komplexes Problem das ich einfach nicht gelöst bekomme...
Brauche echt dringend Hilfe!

ich lasse mit aus einer Datenbank erschiedene Werte ausgeben (das ganze in einem Memo). Jedes der Daten in einer Zeile des Memos.
z.B
Meier
Müller
Schmidt
Meier
Paulus
Meier
Wölki
Rinkel
Schmidt
... usw
Das sind aber nicht alle in der Tabelle enthaltenen Datensätze.
Jetzt möchte ich, das mein Programm auf Knopfdruck Jede dieser Daten erfasst und vergleicht.
Also soll er zuerst "Meier" nehmen, und prüfen ob die Anzahl ALLER Meiers in der Datenbank genau die selbe ist, wie die ALLER Meiers im Memo.
Wenn ja soll der in einem Weiteren Memo irgendwas ausgeben (z.B 'meier anzahl stimmt')
Dann prüft er den zweiten namen, usw.
Wenn wirklich keiner der namen übereinstimmt kommt eine Fahlermeldung.

ist das machbar?


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Do 10.02.2011 um 17:45


Narses - Do 10.02.11 18:48

Moin!

user profile iconvalherf hat folgendes geschrieben Zum zitierten Posting springen:
ist das machbar?
Ja. :nixweiss:

Die spannende Frage ist: wo ist dein Problem? :zwinker: Und was hast du dir bereits für Gedanken zur Lösung gemacht? ;)

cu
Narses


valherf - Do 10.02.11 18:57

hab mal ein Strucktogramm auf ein papier skizziert, und angefangen alles zu Probieren. Scheiterte aber bisher schon in den Kinderschüchen ;)
Wollte es z.B nur mit dem Aller ersten namen testhalber machen. aber schon das klappt nicht so wirklich :(


Tankard - Do 10.02.11 19:09

ist doch ganz einfach.

du nimmst einen namen aus dem memo. gehst jede memozeile durch und incrementierst einen zahler, wenn die namen übereinstimmen.

wenn das alles durchlaufen ist hast du eine variable mit der anzahl der 'meier'.

dann sagst du der datenbank via select folgendes


SQL-Anweisung
1:
select count(name) as Anzahl from MeineTabelle where name like 'meier'                    


und dann vergleicht du die zwei werte. wenn werte gleich sind, foundequalcount=true

den ganzen oberen block packst du in eine schleife die von 0 bis memo.lines.count-1 geht. damit du alle name aus dem memo feld einmal mit deiner db verglichen hast.


wenn das ist was du wolltest.

wenn du alles schoen 1:1 in delphi übersetzt, haste dein problem geloest. ist nichtmal schwer.

Moderiert von user profile iconKlabautermann: SQL-Tags hinzugefügt


valherf - Do 10.02.11 21:06

user profile iconTankard hat folgendes geschrieben Zum zitierten Posting springen:

SQL-Anweisung
1:
select count(name) as Anzahl from MeineTabelle where name like 'meier'                    


select ist doch wohl eher ne Access anweisung?
wie mach ich das in delphi?

den anfang hab ich jetzt schon


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button1Click(Sender: TObject);
VAR
Anzahl,Anzahl2,i:integer;
satz,suche1:string;
begin
  i:=memo2.Lines.Count;
  suche1:=memo2.Lines[0];
  Satz:=memo2.lines.GetText;
  anzahl:=0;
    for i:= 1 to length(Satz) do
     begin
      if suche1 = satz[i] then
      inc(anzahl);
      label1.caption:= IntToStr(anzahl);
     end;


aber wies weiter geht weiß ich nicht so recht...

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

wie kann ich die Zeilen in einer ADOtable zählen?

Moderiert von user profile iconKlabautermann: SQL- und Quote-Tags hinzugefügt


Narses - Do 10.02.11 22:42

Moin!

user profile iconvalherf hat folgendes geschrieben Zum zitierten Posting springen:

SQL-Anweisung
1:
select count(name) as Anzahl from MeineTabelle where name like 'meier'                    
select ist doch wohl eher ne Access anweisung?
wie mach ich das in delphi?
Ähm, was hat denn eine SQL-Anweisung mit Access zu tun? :gruebel:
user profile iconvalherf hat folgendes geschrieben Zum zitierten Posting springen:
wie kann ich die Zeilen in einer ADOtable zählen?
Genau so wie oben angegeben. :idea: ;)

user profile iconvalherf hat folgendes geschrieben Zum zitierten Posting springen:
den anfang hab ich jetzt schon
Öhm :? Was auch immer der Code tun soll, aber probier das mal lieber so: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
  var
    SL: TStringList;
    i, j: Integer;
begin
  SL := TStringList.Create;
  try
    for i := 0 to Memo1.Lines.Count-1 do begin
      j := SL.IndexOf(Memo1.Lines.Strings[i]);
      if (j >= 0then
        SL.Objects[j] := Pointer(Integer(SL.Objects[j]) +1)
      else
        SL.AddObject(Memo1.Lines.Strings[i], Pointer(1));
    end;
    Memo2.Clear;
    for i := 0 to SL.Count-1 do
      Memo2.Lines.Add(Format('String: %s, Anzahl: %d', [SL.Strings[i], Integer(SL.Objects[i])]));
  finally
    SL.Free;
  end;
cu
Narses


bummi - Do 10.02.11 22:50

Narses war einen Tick schneller, aber da ich meines auch gerade fertig habe

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.Button1Click(Sender: TObject);
var
  i:Integer;
  sl:TStringList;
  Procedure AddToCountList(const s:String);
    var
      index:Integer;
    begin
      index := sl.IndexOf(s);
      if index > -1 then sl.Objects[index] := TObject(Integer(sl.Objects[index]) + 1)
      else sl.AddObject(s,TObject(1));
    end;
begin
  sl:=TStringList.Create;
  ProtokollMemo.Lines.Clear;
  try
  For i := 0 to Memo1.Lines.Count - 1 do
       begin
         AddToCountList(Memo1.Lines[i]);
       end;
  for I := 0 to sl.Count - 1 do
      begin
        SuchADODataSet.Close;
        SuchADODataSet.Parameters.ParamByName('Name').Value := sl[i];
        SuchADODataSet.Open;
        if SuchADODataSet.FieldByName('Anzahl').AsInteger <> Integer(sl.Objects[i]) then
            ProtokollMemo.Lines.Add(sl[i] + 'Liste: ' + IntToStr(Integer(sl.Objects[i])) + ' Datenbank: ' + SuchADODataSet.FieldByName('Anzahl').AsString)
        else  ProtokollMemo.Lines.Add(sl[i] +': OK');
      end;
  finally
  sl.Free;
  end;
end;


Tranx - Fr 11.02.11 04:33

Ich denke, dass die Zeilen des Memos zuerst, bevor Du den Vergleich machst, sortiert werden sollten. Dann hast Du in etwa die Daten so vorlieren

Abel
Brüning
..
Maier
Maier
Meier
Meyer
Meyer
Meyer
Müller
Müller
Müller
Müller
..

Dann ist der Vergleich viel einfacher, da Du ja nur die Zeilen von 0 .. x durchlaufen musst und dann den Vergleich einzelner Einträge der ebenfalls sortierten Datenbankeinträge (!!) vergleichen musst.
Du kannst ja die Zähler beider Tabellen unterschiedlich wandern lassen. Wenn Du auf den ersten Meier im Memo triffst, läufst Du alle Meiers des Memo durch und das Gleiche bei der Datenbank. Wobei bei der Datenbank ja die Möglichkeit besteht, diese Auswertung durch die Datenbank per SQL-Abfrage erledigen zu lassen. Dann hast Du die Anzahl der einzelnen Namen auf der Datenbankseite schon mal vorliegen.

Du könntest auch die Einträge in dem Memo in eine Temp-Tabelle überführen und dann die Daten dieser Temp-Tabelle ebenfalls in einer SQL-Abfrage - genauso wie die Originaldaten - auszuwerten. Bei hunderttausenden von Datensätzen wäre dies möglicherweise etwas schneller. Denn bei einer solchen Clusterung der Daten in Form von

Name .. Anzahl

Abel 1
Brüning 1
..
Maier 2
Meier 1
Meyer 3
Müller 4
..

Reduzierst Du ja die Anzahl der zu untersuchenden Datensätze erheblich. Nimm nur die Verteilung der Namen in der Bundesrepublik. Da sind bestimmt von 82.000.000 7.000.000 vom Typ Meyer, Maier, Meier, Mayer, Müller, Schmidt ...

Denk mal drüber nach!