Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQL Abfrage über zwei Tabellen (https://www.delphipraxis.net/168152-sql-abfrage-ueber-zwei-tabellen.html)

citybreaker 8. Mai 2012 09:34

Datenbank: mssql • Version: 2008 • Zugriff über: zeos

SQL Abfrage über zwei Tabellen
 
Hallo zusammen ,

ich hab mal wieder ein Problem was eine SQL-Abfrage angeht. Ich habe in der Abfrage zwei Tabellen verbunden bekomme aber
nicht das Ergebnis was ich möchte.
Tabelle1 hat die Spalten ID, Kunde, Nummer, Klasse, ... und Tabelle2 ID, Tabelle1ID, Status, Datum, ...

Es kommt aber vor das in Tabelle2 nicht immer ein Eintrag für Tabelle1 existiert.
Angezeigt haben möchte ich das Folgendermaßen.

ID (Tabelle1) | Kunde | Nummer | Status (nur wenn in tabelle2 vorhanden ansonsten leer lassen)

Jetzt zum Problem. Wenn kein passender Eintrag in Tabelle2 vorhanden ist wird einfach der nächste Wert vom Status genommen und reingeschrieben
und alles verschiebt sich.
Code:
SELECT Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status FROM Tabelle1, Tabelle2
Wie Frage ich das ganze am besten ab, dass Stauts entsprechend leer gelassen wird? Steh nen bisschen aufm Schlauch.

In Delphi lasse ich mir das ganze dann in einem ListView anzeigen.
Delphi-Quellcode:
TZQuery1.SQL.Text := 'SELECT Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status FROM Tabelle1, Tabelle2';
TZQuery1.Active := true;
TZQuery1.Open;

while not TZQuery1.eof do begin
   ListItem := ListView.Items.Add;
   ListItem.Caption := TZQuery1.FieldByName('ID').AsString;
   ListItem.SubItems.Add(TZQuery1.FieldByName('Kunde').AsString);
   ListItem.SubItems.Add(TZQuery1.FieldByName('Nummer').AsString);
   ListItem.SubItems.Add(TZQuery1.FieldByName('Status').AsString);
   DataSet.Next;
end;

...

DeddyH 8. Mai 2012 09:42

AW: SQL Abfrage über zwei Tabellen
 
SQL-Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
LEFT JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID

citybreaker 8. Mai 2012 09:56

AW: SQL Abfrage über zwei Tabellen
 
Vielen dank. So hab ich mir das vorgestellt. :)

DeddyH 8. Mai 2012 09:59

AW: SQL Abfrage über zwei Tabellen
 
Keine Ursache. Allerdings stelle ich mir die Frage, wieso Du das Query erst auf Active setzt und dann zusätzlich noch Open aufrufst. Soll das so?

citybreaker 8. Mai 2012 10:52

AW: SQL Abfrage über zwei Tabellen
 
Bin mir nicht sicher habe das aber glaube ich mal irgendwo in einem Beispiel Code oder so gesehen. Wie würde es den richtig aussehen?

Eine Frage habe ich jetzt noch zu der SQL-Abfrage was ein WHERE betrifft.

SQL-Code:
// Funktioniert
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
LEFT JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
WHERE
  Tabelle1.Kunde LIKE '%xyz%'

// Funktioniert nicht
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
LEFT JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
WHERE
  Tabelle2.Status LIKE '%1%'

DeddyH 8. Mai 2012 10:56

AW: SQL Abfrage über zwei Tabellen
 
Entweder Open oder Active auf true, alles andere ist doppelt gemoppelt. Zum Statement: was kommt denn hierbei heraus?
SQL-Code:
SELECT
  COUNT(*)
FROM
  Tabelle2
WHERE
  Tabelle2.Status LIKE '%1%'
[edit] Andere Idee (evtl. meinst Du das):
SQL-Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
LEFT JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
AND
  Tabelle2.Status LIKE '%1%'
[/edit]

citybreaker 8. Mai 2012 11:17

AW: SQL Abfrage über zwei Tabellen
 
Damit würden mir aber wieder die ganzen Sachen aus Tabelle1 im ListView fehlen oder?

--- Edit ---
Das zweite hab ich übersehen. Probiere es mal aus. Danke. :)

Mit
SQL-Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
LEFT JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
AND
  Tabelle2.Status LIKE '%1%'
bekomme ich allle Einträge angezeigt, die keinen Eintrag in Tabelle2 haben.

DeddyH 8. Mai 2012 12:12

AW: SQL Abfrage über zwei Tabellen
 
Anders gefragt: gibt es denn überhaupt Datensätze in Tabelle2, die eine 1 im Status-Feld enthalten und mit Tabelle1 verknüpft sind?

citybreaker 8. Mai 2012 12:21

AW: SQL Abfrage über zwei Tabellen
 
Ja gibt es.

Habe Testweise die Tabellen folgendermaßen gefüllt.
Zitat:

Tabelle1
ID, Kunde, Nummer
1;a;100 << hat keinen Eintrag in Tabelle2
2;b;200
3;c;300
4;d;400
5;e;500
6;xyz;600;

Tabelle2
ID, Tabelle1ID, Status
1;2;1
2;3;1
3;4;0
4;5;0
5;6;1
Wenn ich im WHERE Teil in einer Spalte aus Tabelle1 suche funktioniert alles wunderbar.
Sobald ich in einer Spalte in Tabelle2 suche gehts nicht.

Bei WHERE Tabelle2.Status='%%' werden mir alle Spalten angezeigt die einen Eintrag im Status Feld haben.

DeddyH 8. Mai 2012 12:23

AW: SQL Abfrage über zwei Tabellen
 
Von welchem Typ ist denn Status?

citybreaker 8. Mai 2012 12:27

AW: SQL Abfrage über zwei Tabellen
 
Status ist Varchar. 1 und 0 habe ich nur als Beispiel zum Testen genommen.

DeddyH 8. Mai 2012 12:30

AW: SQL Abfrage über zwei Tabellen
 
Anscheinend bin ich aktuell etwas vernagelt. Bekommst Du hiermit Datensätze angezeigt?
SQL-Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
WHERE
  Tabelle2.Status LIKE '%1%'

citybreaker 8. Mai 2012 12:50

AW: SQL Abfrage über zwei Tabellen
 
Dann bin ich ja zum Glück nicht der einzigste der vernagelt ist.

Damit bekomme ich keine Datensätze angezeigt. Benutze ich anstatt WHERE ein AND bekomme ich Datensätze angezeigt ohne Eintrag in Tabelle2 (1;a;100).

DeddyH 8. Mai 2012 13:01

AW: SQL Abfrage über zwei Tabellen
 
Das bedeutet aber doch eigentlich, dass es keine verknüpften Datensätze in Tabelle2 gibt, die eine 1 enthalten. Gleichzeitig hieße das aber, dass Du ohne die WHERE-Klausel keine Datensätze mit einer 1 irgendwo im Status-Feld sehen könntest. Falls doch, dann mache ich gerade eine riesigen Denkfehler.

angos 8. Mai 2012 13:16

AW: SQL Abfrage über zwei Tabellen
 
Zitat:

Zitat von DeddyH (Beitrag 1165319)
Das bedeutet aber doch eigentlich, dass es keine verknüpften Datensätze in Tabelle2 gibt, die eine 1 enthalten. Gleichzeitig hieße das aber, dass Du ohne die WHERE-Klausel keine Datensätze mit einer 1 irgendwo im Status-Feld sehen könntest. Falls doch, dann mache ich gerade eine riesigen Denkfehler.

Über diesen Stolperstein bin ich auch schon öfters gefallen ;)

Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM Tabelle1
LEFT JOIN Tabelle2 
  ON Tabelle2.Tabelle1ID = Tabelle1.ID
  AND Tabelle2.Status LIKE '%1%'
WHERE NOT Tabelle2.Status IS NULL

DeddyH 8. Mai 2012 13:17

AW: SQL Abfrage über zwei Tabellen
 
Wozu einen OUTER JOIN, wenn man dann die NULLs wieder aussortiert?

angos 8. Mai 2012 13:22

AW: SQL Abfrage über zwei Tabellen
 
Stimmt eigentlich auch...aber dann ists doch mit einem INNER JOIN erledigt?!

EDIT: Hab das mal fix mit deinem SQL von oben probiert. Der bringt auf meinem MSSQL-Server wie erwartet folgendes Ergebnis:

2;b;200;1
3;c;300;1
6;xyz;600;1

madas 8. Mai 2012 13:41

AW: SQL Abfrage über zwei Tabellen
 
Bei mir geht es uneter Firebird 2.1 auch:

Code:
select
  t1.ID,
  t1.KUNDE,
  t1.NUMMER,
  t2.STATUS
from TABELLE1 t1
left join TABELLE2 t2 on (t2.TABELLE1_ID = t1.ID)
where (t2.STATUS like '1')
Ergebnis:

ID KUNDE NUMMER STATUS
2 b 200 1
3 c 300 1
6 xyz 600 1

DeddyH 8. Mai 2012 13:43

AW: SQL Abfrage über zwei Tabellen
 
Wenn ich den TE richtig verstanden habe, will er alle DS aus Tabelle1 haben zzgl. evtl. vorhandenen verknüpften aus Tabelle2, die irgendwo im Status-Feld eine 1 stehen haben.

madas 8. Mai 2012 13:59

AW: SQL Abfrage über zwei Tabellen
 
Zitat:

Zitat von DeddyH (Beitrag 1165331)
Wenn ich den TE richtig verstanden habe, will er alle DS aus Tabelle1 haben zzgl. evtl. vorhandenen verknüpften aus Tabelle2, die irgendwo im Status-Feld eine 1 stehen haben.

Code:
select
  t1.ID,
  t1.KUNDE,
  t1.NUMMER,
  t2.STATUS
from TABELLE1 t1
left join TABELLE2 t2 on (t2.TABELLE1_ID = t1.ID) and (t2.STATUS like '1')
Na dann macht er aus dem 'where' ein 'and' und schon hat er, was er will:

Ergebnis:

ID KUNDE NUMMER STATUS
1 a 100 <null>
2 b 200 1
3 c 300 1
4 d 400 <null>
5 e 500 <null>
6 xyz 600 1

DeddyH 8. Mai 2012 14:08

AW: SQL Abfrage über zwei Tabellen
 
Siehe mein Edit in #6 (LIKE ohne Wildcard sieht ein bisschen komisch aus, oder?)

p80286 8. Mai 2012 14:31

AW: SQL Abfrage über zwei Tabellen
 
Könnte es sein, daß es hiermit klappt?
Code:
SELECT
  Tabelle1.ID, Tabelle1.Kunde, Tabelle1.Nummer, Tabelle2.Status
FROM
  Tabelle1
JOIN
  Tabelle2 ON Tabelle2.Tabelle1ID = Tabelle1.ID
WHERE
  (Tabelle2.Status LIKE '%1%'
  or  
  Tabelle2.Status is NULL)
Gruß
K-H

DeddyH 8. Mai 2012 14:35

AW: SQL Abfrage über zwei Tabellen
 
Das ist ja wieder ein INNER JOIN.

p80286 8. Mai 2012 14:41

AW: SQL Abfrage über zwei Tabellen
 
Ok, hier war so oft die Rede von Vernagelt, ich reihe mich ein.
Benutz halt das "LEFT Join"
(ich geb zu ich stehe mit den ANSI-Joins auf Kriegsfuß)

Gruß
K-H

DeddyH 8. Mai 2012 14:43

AW: SQL Abfrage über zwei Tabellen
 
Vielleicht reden wir auch alle an einander vorbei. Warten wir mal ab, ob der TE sich noch einmal meldet.

Iwo Asnet 8. Mai 2012 15:26

AW: SQL Abfrage über zwei Tabellen
 
Wie schon vor mir festgestellt: Es funktioniert auch in MSSQL wie erwartert
SQL-Code:
select * 
  from tabelle1 t1 left join
       tabelle2 t2 on t1.ID=t2.Tabelle1ID
where t2.Status like '%1%'

citybreaker 8. Mai 2012 15:30

AW: SQL Abfrage über zwei Tabellen
 
Funktioniert jetzt, hatte noch nen Fehler im Quellcode. :pale:
Danke für eure Hilfe.

DeddyH 8. Mai 2012 15:33

AW: SQL Abfrage über zwei Tabellen
 
Zitat:

Zitat von Iwo Asnet (Beitrag 1165368)
Wie schon vor mir festgestellt: Es funktioniert auch in MSSQL wie erwartert
SQL-Code:
select * 
  from tabelle1 t1 left join
       tabelle2 t2 on t1.ID=t2.Tabelle1ID
where t2.Status like '%1%'

Ich hatte das heute schon einmal gefragt: wozu ein OUTER JOIN, wenn man die NULLs anschließend mittels Bedingung wieder ausfiltert?

Iwo Asnet 8. Mai 2012 16:09

AW: SQL Abfrage über zwei Tabellen
 
Ich glaub, weil
* Das LEFT JOIN schon mal erwähnt wurde und wir Gewohnheitstiere sind.
* Die Abfrage so auch ohne Probleme auf "ohne Status" erweiterbar ist.

(Der letzte Punkt ist eine billige Ausrede)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:37 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