Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Problem mit distinct (https://www.delphipraxis.net/19918-problem-mit-distinct.html)

Rolf Rostig 10. Apr 2004 20:51


Problem mit distinct
 
Hallo,

ich habe eine FB-Tabelle mit den Feldern ID, RechNr, KundenNr, ArikelNr.
Leider mit doppelten Einträgen der Rechnr und KundenNr.
Nun soll nur die ID und RechNr ohne Duplikate ausgegeben werden.
Mit

SQL-Code:
select distinct RechNr, ID from tabelle
geht es nicht.
Wer hat eine Idee?

grayfox 10. Apr 2004 21:10

Re: Problem mit distinct
 
hallo rolf!

rein aus dem bauch heraus würde ich es so versuchen:
Delphi-Quellcode:
select distinct RechNr, distinct ID from tabelle
alle angaben ohne gewähr ;)

mfg, stefan

Rolf Rostig 10. Apr 2004 21:23

Re: Problem mit distinct
 
Hi Stefan,

leider nicht. :shock:

Chewie 10. Apr 2004 21:39

Re: Problem mit distinct
 
Vielleicht so:

SQL-Code:
SELECT (DISTINCT rechnr), (DISTINCT ID) FROM table
Sorry, ist nur geraten :cat:

Robert_G 10. Apr 2004 23:04

Re: Problem mit distinct
 
Dein Code ist doch vollkommen richtig.
Mit Distinct sorgst du dafür, dass jede Zeile nur einmal vorkommt. Es werden werden also keine doppelten Paare von RechNr & ID ausgegeben.

p.s.:
SQL-Code:
SELECT distinct RechNr, distinct ...
... tut irgendwie weh ;)

Rolf Rostig 11. Apr 2004 11:37

Re: Problem mit distinct
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe ich auch gedacht.
Aber das Ergebnis siehe Bild. :gruebel:

Sharky 11. Apr 2004 11:45

Re: Problem mit distinct
 
Hai Rolf Rostig,

mit distinct wird doch nur verhindert das doppelte Einträge angezeit werden. in deiner Liste gibt es aber keine doppelten paare von RechNr, ID.

Wenn ich dich richtig verstehe möchtest Du ja eine Abfrage die alle RechNr anzeigt die genau einmal in der Tabelle vergeben sind oder?

Rolf Rostig 11. Apr 2004 11:52

Re: Problem mit distinct
 
ja genau :hi:

MarkusB 11. Apr 2004 12:57

Re: Problem mit distinct
 
Hallo Rolf!

Ist das Feld "ID" auch der Primär-Key in Deiner Tabelle?

Wenn ja (was ich auch vermute), dann hat die Klausel "DISTINCT" keine Wirkung in Deiner Abfrage, weil "ID" schon per Definition eindeutig ist (es können keine doppelten Einträge von ID existieren). Deshalb können auch keine doppelten Paare von "RechNr" und "ID" vorkommen.

Wenn Du alle RechNr selektieren willst, die in deiner Tabelle nur genau einmal vorkommen, solltest Du die "GROUP BY" und "HAVING" Klausel verwenden.
Ich würde das etwa so machen:

SQL-Code:
select RechNr
from tabelle
group by RechNr
having count(*) = 1
Viele Grüße
Markus

Robert_G 11. Apr 2004 20:27

Re: Problem mit distinct
 
Zitat:

SQL-Code:
select RechNr
from tabelle
group by RechNr
having count(*) = 1

Markus, hast du dir genau überlegt, was der Code macht?
Du gruppierst nach RechNr. Da du nur RechNr auswählst entspricht es exakt einem...
SQL-Code:
SELECT Distinct RechNr
FROM  tabelle
...oder...
SQL-Code:
SELECT RechNr
FROM  tabelle
GROUP BY RechNr
Das zusätzlich Count(*) = 1 in der HAVING Clause erfordert doch nur unnötigerweise einen weiteren Durchlauf der Daten.

MarkusB 12. Apr 2004 11:31

Re: Problem mit distinct
 
Hi Robert!

SQL-Code:
select RechNr
from tabelle
group by RechNr
having count(*) = 1
Der Code durchläuft die Tabelle und gruppiert (sammelt) alle Datensätze mit der gleichen RechNr (es kann sein, dass sie doppelt oder mehrfach vorkommen – siehe Rolfs Problembeschreibung) in getrennte Gruppen. Dabei wird für jede Gruppe ein Zähler geführt. Der Zähler (COUNT(*))
besagt wie viele Records sich in jeder Gruppe befinden.

Also noch mal meine Überlegung: :gruebel:
1. Tabelle auslesen.
2. Alle Records nach RechNr gruppieren.
3. Untersuchen wie viele Records sich in jeder Gruppe befinden.
4. Nur die RechNr ausgeben, die nur einmal vorkommen (COUNT(*) = 1)

Ich hoffe, dass ich das Problem von Rolf richtig verstanden habe.

Viele Grüße
Markus

Rolf Rostig 12. Apr 2004 12:27

Re: Problem mit distinct
 
Hallo,

Ziel des Ganzen: die doppelten Einträge löschen.

Robert_G 12. Apr 2004 12:51

Re: Problem mit distinct
 
Es wurde doch schon mehrfach gepostet, warum du doppelte Einträge bekommst, wenn du die ID mit selektierst.
Willst du unbedingt EINE von vielen IDs einer RechNr haben dann geht das nur so:
SQL-Code:
SELECT RechNr, min(ID)
FROM  Tabelle
GROUP BY RechNR
@Markus
nochmal: Das Count(*) = 1 in der Having-Clause hat keinen Sinn, denn wenn du NUR nach RechNr gruppierst, dann bekommst du auch nur EINE RechNr.

MarkusB 12. Apr 2004 16:53

Re: Problem mit distinct
 
Liste der Anhänge anzeigen (Anzahl: 3)
Hi Rolf!

Jetzt wo die Aufgabestellung immer klarer wird, habe ich noch eine Frage.
Welcher Datensatz (von denen mit der gleichen RechNr) soll in der Tabelle bleiben?
Der mit der niedrigsten ID, der mit höchsten ID, der mit irgendeiner ID oder sollen sogar alle
als fehlerhaft angesehen und deswegen komplett aus der Tabelle entfernt werden?

@Robert
Meine Abfrage:
SQL-Code:
select RechNr
from tabelle
group by RechNr
having count(*) = 1
liefert die Antwort auf die Aufgabestellung die von Sharky formuliert wurde:
Zitat:

Wenn ich dich richtig verstehe möchtest Du ja eine Abfrage die alle RechNr anzeigt die genau einmal in der Tabelle vergeben sind oder?
Zurückgelieferte Datenmenge siehe Anhang: Datei Query1.jpg
Wobei ich meine, dass
SQL-Code:
having count(*) = 1
das "A&O" der Abfrage ist.

Deine Abfrage:
SQL-Code:
SELECT RechNr, min(ID)
FROM  Tabelle
GROUP BY RechNR
liefert die Antwort auf die folgende Aufgabestellung:
"Zeige DIE niedrigste ID pro RechNr"

Also nicht
Zitat:

Willst du unbedingt EINE von vielen IDs einer RechNr haben
Zurückgelieferte Datenmenge siehe Anhang: Datei Query2.jpg

Als Datenmenge für beide Queries dient die von Rolf zur Verfügung gestellte Tabelle
siehe Anhang: Datei Tabelle.jpg

Viele Grüße
Markus
:gruebel:

Robert_G 12. Apr 2004 17:16

Re: Problem mit distinct
 
Verdammt :wall:
Du hast natürlich vollkommen recht. Ich hatte das Problem falsch verstanden.
Sorry, dass ich so einen Käse verzapft habe. :oops:

Rolf Rostig 14. Apr 2004 11:32

Re: Problem mit distinct
 
Hi Markus,

es ist völlig egal welcher von den doppelten Datensätzen gelöscht wird.
Wichtig ist nur das die RechNr nur einmal vorkommt.
Mit der vorgeschlagenen Lösung ist das auch der Fall.
Jetzt muss ich nur noch die überflüssigen Datensätze löschen, aber das klappt noch nicht.

MarkusB 15. Apr 2004 22:34

Re: Problem mit distinct
 
Hi Rolf!

Um die doppelten Einträge der RechNr aus Deiner Tabelle zu löschen, schlage ich Dir folgende Lösungen vor:

A. SQL-Anweisung: Kurz und knackig, aber sie funktioniert NUR wenn die „id“ in der Tabelle eindeutig ist:
SQL-Code:
delete from tabelle
where id not in (select max(id)
                   from tabelle
               group by rechnr)
B. ein Versuch der allgemeinen Lösung:
Delphi-Quellcode:
procedure my_procedure();
var
   my_query: TQuery;
begin
   my_query := TQuery.Create(self);
   my_query.SQL.Add('select rechnr, max(id) as max_id from test003 group by rechnr');
   my_query.Prepare;
   my_query.Open;

   if my_query.RecordCount <> 0 then
   begin
      Query1.Close;
      Query1.SQL.Clear;
      Query1.SQL.Add('delete from test003');
      Query1.SQL.Add('where rechnr = :rechnr');
      Query1.SQL.Add(' and    id <> :id');

      my_query.first;

      while not my_query.EOF do
      begin
         Query1.ParamByName('rechnr').Value := my_query.FieldbyName('rechnr').AsString;
         Query1.ParamByName('id').Value    := my_query.FieldbyName('max_id').AsInteger;
         Query1.ExecSQL;

         my_query.next;
      end;
   end;

   my_query.Close;
   my_query.Destroy;
end;
Sag bescheid ob es geklappt hat....
An einer eleganteren Lösung (SQL) wäre ich auch interessiert.

Viele Grüße
Markus
:gruebel:

Rolf Rostig 17. Apr 2004 15:45

Re: Problem mit distinct
 
Hi Markus,

ja, mit der Version A hat es schon geklappt.
Vielen Dank für die Hilfe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:18 Uhr.

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