Entwickler-Ecke

Datenbanken - SQL Abfrage (Schnittmenge)


broucker - Do 26.11.09 14:37
Titel: SQL Abfrage (Schnittmenge)
Hallo,

könnte mir irgendjemand von Euch sagen wie ich eine einfache Abfrage in der Gestalt bauen kann:

SELECT distinct p.Nachname, p.Vorname, f.Kurzbezeichnung
FROM Personen as p, Firma as f, PS as ps
WHERE p.FirmaID = f.FirmaID
AND p.PersonID = ps.PersonID
AND ps.StammID = 65

soweit, so gut

wenn ich nun aber alle Personen brauche die die StammID 65 UND 66 haben (also die Schnittmenge nicht beides,
das ginge ja locker mit ... IN (65,66)...) tu ich mir schwerer (vermutlich auch aus Unkenntnis, aber dafür poste ich das mal)

...
AND p.PersonID = ps.PersonID
AND ps.StammID = 65
AND ps.StammID = 66
...

wird immer die leere Menge obwohl es Personen gibt die beides haben (also 65 und 66)

Wäre echt super wenn ich einige hilfreiche Zeichen von Euch bekomme !!

chris


mkinzler - Do 26.11.09 14:43


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
SELECT 
    distinct p.Nachname, 
    p.Vorname, 
    f.Kurzbezeichnung
FROM 
    PS ps 
       join Personen p on p.PersonID = ps.PersonID
           join Firma f on  f.FirmaID = p.FirmaID
WHERE 
    ps.StammID = 65;


broucker - Do 26.11.09 14:57

Ja Danke,
aber das ist ja nur die bereits beschriebene Abfrage wenn ich auf eine StammID abfrage (natürlich schöner mit JOIN :) danke) - die geht ja eh - wenn ich aber auf mehrere verknüpfen will dann hab ich so wie oben beschrieben das Problem

WHERE
ps.StammID = 65 and ps.StammID = 66 and ...


zuma - Do 26.11.09 14:58


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
SELECT 
    distinct p.Nachname, 
    p.Vorname, 
    f.Kurzbezeichnung
FROM 
    PS ps 
       join Personen p on p.PersonID = ps.PersonID
           join Firma f on  f.FirmaID = p.FirmaID
WHERE 
    ps.StammID in (6566);


mkinzler - Do 26.11.09 15:00

Denn bei gleich müsste ein datensatz gleichzeitig alle genannten IDs haben


broucker - Do 26.11.09 15:07

Danke zuma, aber wie oben beschrieben gibt ja das genau nicht die Schnittmenge aus,
sondern alle Personen die die ID 65 haben (zb: 17 Personen) und alle die die ID 66 haben (zb: 20 Personen)
also in Summe 37 Personen stehen dann in der Ergebnisliste (das läuft auch)

Es gibt aber nur 2 Personen die ID 65 und ID 66 haben, d.h. die Ergebnisliste soll NUR die 2 Personen ausweisen

danke


baka0815 - Do 26.11.09 15:12


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
SELECT 
    p.Nachname, 
    p.Vorname, 
    f.Kurzbezeichnung,
    count(*)
FROM 
    PS ps 
       join Personen p on p.PersonID = ps.PersonID
           join Firma f on  f.FirmaID = p.FirmaID
GROUP BY
    p.Nachname, 
    p.Vorname, 
    f.Kurzbezeichnung
WHERE 
    ps.StammID in (6566)
HAVING
    count(*) > 1

?


mkinzler - Do 26.11.09 15:12

Dann musst du andhand eines anderes Feldes Joinen ( Name o.ä)


broucker - Do 26.11.09 15:21

@baka0815: das durchblick ich jetzt grad nicht, ein schneller Paste in den SQL Server brachte Fehler

@mkinzler: die Joins funktionieren ja nur die abfrage die ich UND Verknüpfen will geht nicht, oder wie meinst Du das sonst ?


mkinzler - Do 26.11.09 15:29

Da ein Datensatz genau eine ID hat und du meinst, dass eine Person mehrere hat, dann existieren mehrere Datensätze für diese Person mehrere Datensätze.

AmBesten du postest mal eine Beschreibung deiner Datenbank


broucker - Do 26.11.09 16:01

ich Versuchs mal:

Personen: PersonID,Name,...,FirmaID //Personenstammdaten, jede Person kann in einer Firma arbeiten (keine n:m Bez. da so gewünscht)
Firma: FirmaID,Firmenname,... //Firmenstammdaten
PS: StammID, PersonID //n:m Hilfstabelle Person kann mehrere Stammeinträge haben (Kategorien von Personen)
Stamm: StammID,Art,Bezeichnung //Kategorien ('Weihnachsgrüße', 'Schulung_1 erhalten', 'Schulung_2 erhalten', ...)

Es gibt also mehrere StammID's die eine Person haben kann und ich brauch als Bsp dann genau die Personen
die 'Schulung_1 erhalten' UND 'Schulung_2 erhalten' haben (nur 'Schulung_1 erhalten' wäre zuwenig, diese Personen also nicht)

Danke für Euren Einsatz !!!


zuma - Do 26.11.09 17:29

müsste dann doch in etwa so gehen ?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Select p.Nachname, p.Vorname, f.Kurzbezeichnung
from Stamm s
join PS ps on ps.StammID = s.StammID
join Personen p on p.PersonID = ps.PersonID
join Firma f on  f.FirmaID = p.FirmaID 
where s.Schulung1_erhalten = True and Schulung2_erhalten = True


Pseudo:
lies alle aus Stamm, deren Schulungsbedingungen zutreffen,
joine über die stammid die hilfstabelle,
joine die personen über die personenid aus der hilfstabelle
joine die firmen über die firmenid aus der personentabelle
und wähle die felder name, vorname, kurzbez


alzaimar - Do 26.11.09 17:55

Eine Person kann mechfach in der Tabelle vorkommen. Sie ist durch ihre PersonenID identifiziert.
Wenn wir nun alle Personen mit sich selbst verknüpfen bekommen wir eine (ziemlich lange Tabelle), in der jeder Eintrag einer Person mit sich selbst und mit allen anderen Einträgen der gleichen Person verknüpft ist.
Eine Tabelle bestehend aus (P1-a, P1-b, P2-a) würde durch ein DISTINCT JOIN so aussehen:

Quelltext
1:
2:
3:
4:
5:
P1-a   P1-a
P1-a   P1-b
P1-b   P1-b
P1-b   P1-a
P2-a   P2-a

Nun wollen wir die Personen herausfiltern, die als 2.Eigenschaft a und b besitzen.... Das ist dann einfach.


SQL-Anweisung
1:
2:
3:
4:
5:
6:
Select distinct P1.PersonID
  from Person P1 
       Join Person P2 
         on P1.PersonID = P2.PersonID
 Where P1.StammID = 65 
   and P2.StammID = 66


broucker - Mo 30.11.09 21:01

bin Morgen wieder im Büro und seh mir das mal an

vielen Dank vorerstmal !!!!!!


broucker - Mi 02.12.09 16:39

Danke Euch !
Problem ist nicht mehr da (Lösung siehe alzaimar)