Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL Abfrage mit Distinct - Unterdrücken doppelter Datensätze (https://www.delphipraxis.net/57100-sql-abfrage-mit-distinct-unterdruecken-doppelter-datensaetze.html)

needatip 15. Nov 2005 19:52

Datenbank: SQL Sever • Version: 2000 • Zugriff über: ADO

SQL Abfrage mit Distinct - Unterdrücken doppelter Datensätze
 
Hallo, ich habe folgendes Problem mit einer SQL Abfrage.
Ich habe 2 Tabellen mit folgendem Aufbau

1. Tabelle Lager
I_Nummer (Primärschlüssel)
Warengruppe
Bezeichnung

2. Tabelle Bilder
NR (Primärschlüssel)
LagerNr
Name

Nun erstelle ich eine Abfrage wie folgt.

SQL-Code:
SELECT DISTINCT LAGER.I_Nummer, LAGER.Warengruppe
FROM LAGER INNER JOIN
     Bilder ON LAGER.I_Nummer = Bilder.LagerNr
ORDER BY LAGER.Warengruppe
Es werden von der Lager-Tabelle nur jeweils ein Datensatz ausgegeben, was ich auch möchte.

Sobald ich aber auch das Feld 'NR' der Bilder-Tabelle mit angebe bekomme ich auch immer die doppelten Datensätze angezeigt.

SQL-Code:
SELECT DISTINCT LAGER.I_Nummer, LAGER.Warengruppe, Bilder.LagerNr, Bilder.NR
FROM LAGER INNER JOIN
     Bilder ON LAGER.I_Nummer = Bilder.LagerNr
ORDER BY LAGER.Warengruppe
Wie kann ich das verhindern, so dass nur ein Datensatz von der Lagertabelle ausgegeben wird?

Nightshade 15. Nov 2005 20:08

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Versuch mal ein :

SQL-Code:
SELECT DISTINCT LAGER.I_Nummer, LAGER.Warengruppe, Bilder.LagerNr, Bilder.NR
FROM LAGER INNER JOIN
     Bilder ON LAGER.I_Nummer = Bilder.LagerNr
ORDER BY LAGER.Warengruppe
GROUP my Lager.I_Nummer

needatip 15. Nov 2005 20:20

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Das funktioniert aber nicht.
Da bekomme ich folgenden Fehler vom SQL Server zurück.

Zitat:

Falsche Syntax in der Nähe des Group-Schlüsselwortes.
Das "my" hab ich natürlich durch "BY" ersetzt.

mikhal 16. Nov 2005 05:11

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Die Reihenfolge von Group By und Order By ist vertauscht.

Grüße
Mikhal

[Edit] Rechtschreibfehler...[/edit]

marabu 16. Nov 2005 06:24

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Guten Morgen.

Zitat:

Zitat von needatip
SQL-Code:
SELECT DISTINCT LAGER.I_Nummer, LAGER.Warengruppe
FROM LAGER INNER JOIN Bilder ON LAGER.I_Nummer = Bilder.LagerNr
ORDER BY LAGER.Warengruppe
Es werden von der Lager-Tabelle nur jeweils ein Datensatz ausgegeben, was ich auch möchte.

Kein Wunder. Diese Abfrage wird vom query optimizer vereinfacht zu:

SQL-Code:
SELECT LAGER.I_Nummer, LAGER.Warengruppe
FROM LAGER
ORDER BY LAGER.Warengruppe
Zitat:

Zitat von needatip
Sobald ich aber auch das Feld 'NR' der Bilder-Tabelle mit angebe bekomme ich auch immer die doppelten Datensätze angezeigt.

SQL-Code:
SELECT DISTINCT LAGER.I_Nummer, LAGER.Warengruppe, Bilder.LagerNr, Bilder.NR
FROM LAGER INNER JOIN Bilder ON LAGER.I_Nummer = Bilder.LagerNr
ORDER BY LAGER.Warengruppe
Wie kann ich das verhindern, so dass nur ein Datensatz von der Lagertabelle ausgegeben wird?

Auch hier wirft der query optimizer dein DISTINCT raus, weil es keinen Sinn macht. Wenn du den Fremdschlüssel in der abhängigen Tabelle per DRI (declarative referential integrity) so geschützt hast, dass Bilder ohne zugehörigen Eintrag in der Lagertabelle unmöglich sind, dann erhältst du bei deiner Abfrage natürlich genau so viele Tupel im result set, wie Tupel in deiner Bilder-Tabelle sind.

Was hast du vor? Offensichtlich hast du kein, ein oder mehrere Bilder zu jeder LagerNr. Wenn du nur ein Bild von vielen möglichen auswählen willst, dann musst du vor dem Join die Bilder-Tabelle filtern.

Grüße vom marabu

needatip 16. Nov 2005 07:10

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Sehr gut erklärt.
Ich möchte jedem Eintrag in der Lagertabelle den ersten Eintrag in der Bildtabelle zuordnen.
Es gibt in der Bildtabelle entweder keines,eines oder viele Bilder, die zu einem Eintrag in der Lagertabelle gehören.
Kannst Du mir bitte helfen den SQL Befehl zusammenzubauen und das mit dem Filter erklären?
Danke.

marabu 16. Nov 2005 07:37

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
Gerne. Du hast eine master-detail relationship zwischen Lager M und Bilder D. Da wir keine mächtigeren Sprachmittel für die Formulierung eines theta joins zur Verfügung haben, arbeiten wir mit einer "view" um die gewünschte (0,1) Komplexität der Beziehung für den folgenden equi join herzustellen:
SQL-Code:
SELECT M.I_Nummer, M.Warengruppe, D.NR
FROM LAGER M
INNER JOIN (
  SELECT LagerNr, MIN(NR) AS NR FROM Bilder GROUP BY LagerNr
) AS D ON M.I_Nummer = D.LagerNr
ORDER BY M.Warengruppe
Alles klar?

Für die Namensgebung in Datenbanken gibt es best practices. Tabellen tragen in der Regel den entity name im Plural. Aber dein Datenbank-Design ist bestimmt noch nicht fertig - oder?

marabu

needatip 16. Nov 2005 08:11

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
:thumb: Hey wahnsinn ! Super !!!!
Hab jetzt noch folgendes Problem.
Ich muss noch ergänzen ob die Lagereinträge bestimmte Werte haben, die ich vorher bestimme.
Also in etwa so:

z.B.
SQL-Code:
WHERE M.Warengruppe IN (10,20,30)
Wo und wie baue ich das noch mit ein?
(Ich bin noch kein SQL-Weltmeister) :roll:

Dann bin ich fertig mit meinem SQL Befehl.
Danke.

marabu 16. Nov 2005 08:15

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
SQL-Code:
SELECT M.I_Nummer, M.Warengruppe, D.NR
FROM LAGER M
INNER JOIN (
  SELECT LagerNr, MIN(NR) AS NR FROM Bilder GROUP BY LagerNr
) AS D ON M.I_Nummer = D.LagerNr
WHERE M.Warengruppe IN (:wg)
ORDER BY M.Warengruppe
Fertig...

needatip 16. Nov 2005 08:49

Re: SQL Abfrage mit Distinct - Unterdrücken doppelter Datens
 
:hello: Das nenn ich schnelle und kompetente Hilfe.
Danke nochmals.


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

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