Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

SQL Statment der komplexeren Art

Empfohlene Antworten

Veröffentlicht

Hab gerade ne Frage von nem Kollegen bekommen, der studiert.

Dachte anfangs, dass es simpel ist, aber entweder steh ich auf dem Schlauch oder es ist tatsächlich kompliziert.

Here it is:

Es gibt drei Tabellen:

MA, BEZ, PRO.

MA hat MA_NR (Mitarbeiternummer), MA_NAME(Mitarbeitername)

PRO hat PRO_NR(Projektnummer), PRO_ORT(Projektort)

BEZ hat BEZ_MANR(Mitarbeiternummer), BEZ_PRONR(Projektnummer)

Wie bekomme ich alle MA_NAME, die an allen Projekten an einem bestimmten PRO_ORT beteiligt sind.

Merci

D_Z

Ich denk irgendwie immernoch, dass es simpel ist.....weiss auch nicht wieso.

(wahrscheinlich vertu ich mich :) )

Was spricht dagegen, INNER JOIN's ueber die 3 Tabellen zu machen, den MA_NAME zu selektieren und als Bedingung ein WHERE PRO_ORT = 'blabla' zu setzen?

Goos


SELECT 

   MA_NAME 

FROM 

   MA, BEZ, PRO 

WHERE

   MA_NR = BEZ_MANR AND

   PRO_NR = BEZ_PRONR AND

   BEZ_PRONR IN (

      SELECT PRO_NR FROM PRO

   ) AND

   PRO_ORT = 'Rosenheim'

das wäre mein Vorschlag, ist aber ungetestet

  • Autor
Ich denk irgendwie immernoch, dass es simpel ist.....weiss auch nicht wieso.

(wahrscheinlich vertu ich mich :) )

Was spricht dagegen, INNER JOIN's ueber die 3 Tabellen zu machen, den MA_NAME zu selektieren und als Bedingung ein WHERE PRO_ORT = 'blabla' zu setzen?

Goos

Weil du dann alle bekommst, die an einem oder mehreren Projekten in 'Rosenheim' arbeiten. Du darfst aber nur die kriegen, die an ALLEN Projekten einer Stadt beteiligt sind.

  • Autor

SELECT 

   MA_NAME 

FROM 

   MA, BEZ, PRO 

WHERE

   MA_NR = BEZ_MANR AND

   PRO_NR = BEZ_PRONR AND

   BEZ_PRONR IN (

      SELECT PRO_NR FROM PRO

   ) AND

   PRO_ORT = 'Rosenheim'

das wäre mein Vorschlag, ist aber ungetestet

Auch nicht, leider

Weil du dann alle bekommst, die an einem oder mehreren Projekten in 'Rosenheim' arbeiten. Du darfst aber nur die kriegen, die an ALLEN Projekten einer Stadt beteiligt sind.

*lach*...irgendwie hatte ich doch geahnt, dass ich irgendwas ueberlesen hab :D

Wer nur die bekommen will, welche an allen Projekten aus einer Stadt arbeiten, der muesste mal spontan gedacht das ganze noch Gruppieren und in der Having Klausel einen Count vergleich machen. :)

Goos

Das sollte dann irgendwie so aussehen :

SELECT MA.MA_NAME FROM MA 
INNER JOIN BEZ ON MA.MA_NR = BEZ.BEZ_MANR
INNER JOIN PRO ON BEZ.BEZ_PRONR = PRO.PRO_NR
WHERE PRO.PRO_ORT = 'MyHomeTown'
GROUP BY MA.MA_NAME
HAVING COUNT(BEZ.BEZ_MANR) = (SELECT COUNT(PRO_NR) FROM PRO WHERE PRO_ORT = 'MyHomeTown') [/PHP]

Ich habs nicht getestet, aber mir Muehe gegeben ;)

Ich geh also davon aus, dass es funktioniert.

Goos

Also hier mal n ungetestetes SQL:



SELECT MA_Name FROM MA

JOIN BEZ ON Ma_NR = Bez_MANR

JOIN PRO ON Bez_ProNr = Pro_Nr AND Bez_ProNr = ANY

(SELECT Pro_Nr FROM PRO WHERE Pro_Ort = 'EinOrt')


werd das vielleicht nachher mal kurz testen, denke aber das sollte so gehn

Statt = ANY kann man auch IN verwenden

Du gibst die Mitarbeiter mehrfach zurueck und hast ausserdem auch das "die an ALLEN Projekten..." uebersehen.

Goos

Ein distinct ist dein Freund ;) und ich hab ja nicht gesagt, das das schon ultimativ ausgearbeitet ist.

In ALLEN Projekten macht das = ANY (...

Ein distinct ist dein Freund ;) und ich hab ja nicht gesagt, das das schon ultimativ ausgearbeitet ist.

Ok, darueber wollen wir mal hinwegsehen ;)

In ALLEN Projekten macht das = ANY (...

Das allerdings ist wohl nur ein Geruecht. :D

Any liefert TRUE zurueck, falls der ausdruck mit irgendeinem Wert aus deinem Subquery uebereinstimmt (also nix mit "an allen Projekten".

Vielleicht hast du aber auch ALL gemeint, was TRUE zrueckgibt wenn der Ausduck mit allen Werten aus deinem Subquery uebereinstimmt.

Das ist hier leider auch nicht moeglich, da eine einzelne Zeile deines ersten Resultsets immer nur mit einem Projekt verbunden ist und deshalb ein ALL auf mehrere Projektnummern grundsaetzlich zum scheitern verurteilt ist.

Goos

Wenn ein Mitarbeiter in allen Projekten mitarbeitet, dann arbeitet er doch, laut dem Datenmodell, auch an allen Orten, oder sehe ich das falsch?

Wenn das so ist, muss der Ort gar nicht in die Where-Klausel. Dann geht die Abfrage doch so:

select ma_name, 'Berlin'

from bez, ma

where ma.ma_nr = bez.bez_manr

having count(bez_pronr) = (select count(pro_nr) from pro)

group by bez_manr, ma_name;

Nee, ist ja falsch, sehe ich gerade. Die Mitarbeiter sollen ja nur an allen Projekten an diesem Ort beteiligt sein.

Nee, ist ja falsch, sehe ich gerade. Die Mitarbeiter sollen ja nur an allen Projekten an diesem Ort beteiligt sein.

Das ueberliest sich sehr gut und leicht wie ich aus eigener Erfahrung weiss.

:bimei

Goos

Das sollte dann irgendwie so aussehen :

SELECT MA.MA_NAME FROM MA 
INNER JOIN BEZ ON MA.MA_NR = BEZ.BEZ_MANR
INNER JOIN PRO ON BEZ.BEZ_PRONR = PRO.PRO_NR
WHERE PRO.PRO_ORT = 'MyHomeTown'
GROUP BY MA.MA_NAME
HAVING COUNT(BEZ.BEZ_MANR) = (SELECT COUNT(PRO_NR) FROM PRO WHERE PRO_ORT = 'MyHomeTown') [/PHP]

Ich habs nicht getestet, aber mir Muehe gegeben ;)

Ich geh also davon aus, dass es funktioniert.

Goos

Ich glaub nicht, dass das geht. Mal angenommen, an diesem Ort laufen 3 Projekte. Und der Mitarbeiter ist in 3 Projekten, die aber nicht alle zwangsläufig an diesem Ort sind. Diese Mitarbeiter würden mit dem Statement doch auch selektiert, oder?

Ich glaub nicht, dass das geht. Mal angenommen, an diesem Ort laufen 3 Projekte. Und der Mitarbeiter ist in 3 Projekten, die aber nicht alle zwangsläufig an diesem Ort sind. Diese Mitarbeiter würden mit dem Statement doch auch selektiert, oder?

Nein wuerden sie meiner Meinung nacht nicht. Den Fall, welchen du meinst haetten wir, wenn man das

WHERE PRO.PRO_ORT = 'MyHomeTown'

weglassen wuerde. Dann waer es ein reiner Vergleich der Anzahl, unabhaengig vom Ort.

Durch diese Where Klausel bezieht sich das ganze aber auch nur auf Results die auch direkt mit dem entsprechenden Ort verknuepft sind.

Goos

Nein wuerden sie meiner Meinung nacht nicht. Den Fall, welchen du meinst haetten wir, wenn man das

WHERE PRO.PRO_ORT = 'MyHomeTown'

weglassen wuerde. Dann waer es ein reiner Vergleich der Anzahl, unabhaengig vom Ort.

Durch diese Where Klausel bezieht sich das ganze aber auch nur auf Results die auch direkt mit dem entsprechenden Ort verknuepft sind.

Goos

Stimmt, Du hast recht, damit hats wirklich funktioniert.

werd das vielleicht nachher mal kurz testen, denke aber das sollte so gehn

Hab das gerade getestet. Bis auf das Problem, das MySQL mit dem Subselect hat geht es. Mit Distinct eben, um die Namen nicht doppelt zu bekommen.

Hab das gerade getestet. Bis auf das Problem, das MySQL mit dem Subselect hat geht es. Mit Distinct eben, um die Namen nicht doppelt zu bekommen.

Hat auch keiner gesagt, dass es nicht laeuft.

Es liefert halt keine korrekten Ergebnisse :)

Goos

Es liefert halt keine korrekten Ergebnisse :)

Doch tut es, nur jeden Mitarbeiter eben für jedes Projekt in dem er arbeitet einmal. Sollte er in mehr als einem arbeiten steht er halt mehrmals da. Aber wie gesagt hilft ein kleines distinct ;)

Doch tut es, nur jeden Mitarbeiter eben für jedes Projekt in dem er arbeitet einmal. Sollte er in mehr als einem arbeiten steht er halt mehrmals da. Aber wie gesagt hilft ein kleines distinct ;)

Genau, fuer jeden Mitarbeiter der an einem Projekt am gegebenen Ort arbeitet einmal. Mit distinct dann jeden Mitarbeiter einmal, der an mindestens einem Projekt des gegebenen Ortes arbeitet.

Herauskommen sollten aber nur Mitarbeiter die an ALLEN Projekten zu einem bestimmten Ort arbeiten und genau das kriegst nicht zurueck.

Goos

Genau, fuer jeden Mitarbeiter der an einem Projekt am gegebenen Ort arbeitet einmal. Mit distinct dann jeden Mitarbeiter einmal, der an mindestens einem Projekt des gegebenen Ortes arbeitet.

Herauskommen sollten aber nur Mitarbeiter die an ALLEN Projekten zu einem bestimmten Ort arbeiten und genau das kriegst nicht zurueck.

Goos

Wie bekomme ich alle MA_NAME, die an allen Projekten an einem bestimmten PRO_ORT beteiligt sind.


[i][b]alle Mitarbeiter[/b][/i]


SELECT MA_Name FROM MA


[i][b]hier die Verknüpfung zu den Projekten[/b][/i]


JOIN BEZ ON Ma_NR = Bez_MANR

JOIN PRO ON Bez_ProNr = Pro_Nr 


[i][b]in allen Projekten[/b][/i]


AND Bez_ProNr = ANY


[b][i] an einem bestimmten Ort[/i][/b]


(SELECT Pro_Nr FROM PRO WHERE Pro_Ort = 'EinOrt')


Distinct filtert nur Sätze raus, die im Ergebnis schon vorhanden sind, ähnlich deinem Group By

SQL kann so einfach sein...

EDIT: Es sagt keiner, dass deins falsch ist, nur sehr kompliziert. Und die Verknüpfung über etwas recht allgemeines wie eine Anzahl ist eben nich wirklich schön IMHO

EDIT2:

Ups, glaub ich hab mich da wirklich verrant und was übersehen... muss mir das nochmal durch den Kopf gehen lassen.

SQL kann so einfach sein...

... genauso wie jemand der sich weit aus dem Fenster lehnt auch einfach mal schnell rausfallen kann ;)

[Code]

Distinct filtert nur Sätze raus, die im Ergebnis schon vorhanden sind, ähnlich deinem Group By

Richtig, der Unterschied besteht in dem Fall quasi darin, dass dein Distinct keine Bedingung haben kann.

[Code]

EDIT: Es sagt keiner, dass deins falsch ist, nur sehr kompliziert. Und die Verknüpfung über etwas recht allgemeines wie eine Anzahl ist eben nich wirklich schön IMHO

Natuerlich hat keiner gesagt, dass meines flasch ist, aber ich behaupte halt, dass dein Ansatz falsch ist.

Weiterhin behaupte ich, dass es nicht viel einfacher als in meinem Ansatz zu realisieren geht.

Allerdings lass ich mich da auch gerne eines besseren belehren. :)

Du hast nicht zufaellig gelesen, was ich weiter oben schon ueber dein ANY geschrieben hab?

Vielleicht koenntest das ja mal kommentieren.

Du solltest dir vielleicht auch mal eine kleine Test-DB machen und deine "Loesung" dort kurz ueberpruefen. (Ich hab das gerade mal kurz gemacht und bin deshalb auch in meiner Meinung bestaerkt, dass deine Loesung aus Gruenden die ich schon weiter oben genannt gabe, nicht funktioniert)

Goos :)

  • Autor
...Du solltest dir vielleicht auch mal eine kleine Test-DB machen und deine "Loesung" dort kurz ueberpruefen. ...

Das hab ich auch gemacht.

Hab immer noch keine eigene Lösung, hab diese Woche aber auch nicht daran gearbeitet.

Find ich klasse, dass ihr immer noch dabei seid.

Ich versuchs auch wieder.

Grüsse

D_Z

Hab gerade ne Frage von nem Kollegen bekommen, der studiert.

Dachte anfangs, dass es simpel ist, aber entweder steh ich auf dem Schlauch oder es ist tatsächlich kompliziert.

Here it is:

Es gibt drei Tabellen:

MA, BEZ, PRO.

MA hat MA_NR (Mitarbeiternummer), MA_NAME(Mitarbeitername)

PRO hat PRO_NR(Projektnummer), PRO_ORT(Projektort)

BEZ hat BEZ_MANR(Mitarbeiternummer), BEZ_PRONR(Projektnummer)

Wie bekomme ich alle MA_NAME, die an allen Projekten an einem bestimmten PRO_ORT beteiligt sind.

Merci

D_Z

was ist mit allen Projekten gemeint?? ich sehe kein Projekt Feld oder hab ich was überlesen? ich seh nur eine Projekt nummer und dazu immer einen Ort also der PK der tabelle PRO denk ich ma ein autowert. wenn mehrere Projektnummern einen Ort haben oder andersherum ist doch die ganze DB nichtmal in der Normalform.

also kann man doch auch nur abfragen welche mitarbeiter an einem bestimmten ort arbeiten also ist das ganze eine normalisierte N:M beziehung oder lieg ich da falsch????

lese mich eben erst in diese ganze geschichte ein :rolleyes:

Tabelle MA

mit Primärschlüssel MA_Nr und dem Namen MA_Name

Tabelle BEZ

mit den beiden Fremdschlüsseln BEZ_MANR und BEZ_PRONR

Tabelle PRO

mit Primärschlüssel PRO_NR und dem Ort PRO_ORT

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.