WinFuture-Forum.de: [gelöst] mySQL Join Problem - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

[gelöst] mySQL Join Problem left join gibt immer NULL aus


#1 Mitglied ist offline   J000S 

  • Gruppe: aktive Mitglieder
  • Beiträge: 2.051
  • Beigetreten: 13. Juni 09
  • Reputation: 38
  • Geschlecht:Männlich
  • Wohnort:C:\Home
  • Interessen:Computer, Feuerwehr, Sport

geschrieben 20. November 2015 - 14:31

Hallo zusammen,

ich bin gerade etwas am verzweifeln, weil ich irgendeinen logik Fehler in meiner sql abfrage nicht entdecken kann... Ich musste eine Tabelle in zwei aufteilen um so keine doppelten einträge zu erstellen.

Habe also folgende Situation:

Tabelle 1 (berichte):
[...] = unrelevante spalten

id | sid| gruppe | nummer | datum | [...]
600 | 2015 | 1 | 3 | 20.11.2015 | [...]
601 | 2015 | 1 | 78 | 20.11.2015 | [...]
602 | 2015 | 1 | 321 | 20.11.2015 | [...]


Tabelle 2 (bilder):
[...] = unrelevante spalten

bild_id | bericht_id | pfad | [...]
1 | 600 | "pfad/pfad/pfad" | [...]
2 | 600 | "pfad2/pfad2/pfad2" | [...]
3 | 602 | "pfad3/pfad3/pfad3" | [...]
4 | 602 | "pfad4/pfad4/pfad4" | [...]

Ich möchte nun mit einer Abfrage EINEN Eintrag aus der Tabelle bilder abfragen... Leider bekomme ich immer NULL für alle Spalten der Tabelle bilder ausgegeben. Es kann durchaus sein, dass einige Zeilen NULL ergeben, da es keine entsprechenden Einträge gibt. Allerdings gibt es GENERELL für alle NULL aus :angry:

Meine Abfrage lautet wiefolgt:
SELECT * FROM berichte LEFT JOIN (SELECT * FROM bilder LIMIT 1) as bilder ON berichte.id=bilder.bericht_id 
WHERE berichte.sid=2015 AND berichte.gruppe=1 ORDER BY STR_TO_DATE((berichte.datum), '%d.%m.%Y') DESC,berichte.nummer DESC LIMIT 10


Das Ergebnis was ich Erhalte lautet dann:
id | sid| gruppe | nummer | datum | [...] | bild_id | bericht_id | pfad | [...]
600 | 2015 | 1 | 3 | 20.11.2015 | [...] | NULL | NULL | NULL | [NULL]
601 | 2015 | 1 | 78 | 20.11.2015 | [...] | NULL | NULL | NULL | [NULL]
602 | 2015 | 1 | 321 | 20.11.2015 | [...] | NULL | NULL | NULL | [NULL]

Eigentlich sollte das Ergebnis ja so lauten:
id | sid| gruppe | nummer | datum | [...] | bild_id | bericht_id | pfad | [...]
600 | 2015 | 1 | 3 | 20.11.2015 | [...] | 1 | 600 | "pfad/pfad/pfad" | [NULL]
601 | 2015 | 1 | 78 | 20.11.2015 | [...] | NULL | NULL | NULL | [NULL]
602 | 2015 | 1 | 321 | 20.11.2015 | [...] | 3 | 602 | "pfad3/pfad3/pfad3" | [NULL]


Ich hoffe ich habe mein Problem darstellen können und hoffe, dass jemand die Lösung kennt :)


EDIT: Hatte vorher einen INNER JOIN... aber dier gibt dann gar nix aus

Dieser Beitrag wurde von J000S bearbeitet: 20. November 2015 - 15:25

0

Anzeige



#2 Mitglied ist offline   Sturmovik 

  • Gruppe: aktive Mitglieder
  • Beiträge: 3.776
  • Beigetreten: 10. Januar 08
  • Reputation: 445
  • Geschlecht:unbekannt
  • Wohnort:In Reichweite der Kaffeemaschine
  • Interessen:IT, Luftfahrt, historische Technik

geschrieben 20. November 2015 - 14:42

Warum ... JOIN (SELECT * FROM bilder LIMIT 1) ?
Das ist meiner Meinung nach Quatsch.

Erstmal beide Tabellen joinen und dann auf die Bild-ID Filtern, die du haben willst.
«Geschichte wiederholt sich nicht, aber sie reimt sich» (Mark Twain)

Unix won't hold your hand. You wanna shoot your foot, Unix reliably delivers the shot.

True Cloudstorage
0

#3 Mitglied ist offline   J000S 

  • Gruppe: aktive Mitglieder
  • Beiträge: 2.051
  • Beigetreten: 13. Juni 09
  • Reputation: 38
  • Geschlecht:Männlich
  • Wohnort:C:\Home
  • Interessen:Computer, Feuerwehr, Sport

geschrieben 20. November 2015 - 14:47

Naja ich will ja aus der Tabelle bilder nur EINEN Eintrag. Wenn ich "JOIN bilder" nehme kommen ja alle


EDIT: Ich habe glaube ich die (eine) Lösung gefunden:

SELECT * FROM berichte LEFT JOIN bilder ON berichte.id=bilder.bericht_id 
WHERE berichte.sid=2015 AND berichte.gruppe=1 GROUP BY berichte.id ORDER BY STR_TO_DATE((berichte.datum), '%d.%m.%Y') DESC,berichte.nummer DESC LIMIT 10


Habe das (SELECT FROM...) ersetzt und ein GROUP BY berichte.id eingefügt.
Das scheint das Problem behoben zu haben.

Dieser Beitrag wurde von J000S bearbeitet: 20. November 2015 - 15:19

0

#4 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 20. November 2015 - 16:13

Neneneeneee :shock:

Bloß nicht. Finger weg von SELECT * ... GROUP BY!

Was möchtest Du überhaupt haben mit Deiner Abfrage? Und was steht wo wie drin, ie: wie sehen die Abhängigkeiten aus? Möglicherweise kannst Du statt LEFT auch INNER verwenden, je nach Struktur.

In etwa muß die Abfrage so aussehen:
SELECT b.id, b.sid, b.gruppe, b.nummer, b.datum, -- und ggf andere
r.bericht_id, r.pfad -- und ggf andere
FROM bilder AS b
INNER JOIN berichte AS r ON (b.bericht_id=r.id) -- für den Fall, daß jedes Bild zumindest einen Eintrag in dem Berichten hat; ansonsten LEFT bzw RIGHT OUTER, wenn es auch "schwebende" Bilder ohne diese Referenz gibt

WHERE <bedingung>




und dann ist jetzt die Frage, was GENAU Du haben willst. GROUP BY geht in keinem Fall mit "*" als Spaltenidentifikator; für Gruppierungen mußt Du:

1. Alle zu gruppierenden Spalten im SELECT *und* im GROUP BY-Teil anführen
2. Nicht gruppierte Spalten aus SELECT rauswerfen (sonst gibt MySQL Müll aus)
3. Die gruppierten Spalten in Aggregatfunktionen stecken. Also MIN(), MAX(), AVG(), COUNT() und so weiter und so weiter, je nachdem was Du halt brauchst.

Für "individuell" gibt's statt GROUP BY stattdessen SELECT DISTINCT und Du müßtest dafür sorgen, daß Einträge im Resultset nur soweit spezifiziert werden, daß Eindeutigkeit auch festgestellt werden kann:

SELECT DISTINCT jahr,monat,tag FROM datum LIMIT 2 mag zum Beispiel
2015|01|02
2015|01|03
ausgeben; ein SELECT DISTINCT jahr, monat FROM DATUM LIMIT 2 über denselben Datenbestand würde hier
2015|01
ausgeben, weil eben DAS unter den Bedingungen der Abfrage DISTINCT (= eindeutig) ist.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
0

#5 Mitglied ist offline   J000S 

  • Gruppe: aktive Mitglieder
  • Beiträge: 2.051
  • Beigetreten: 13. Juni 09
  • Reputation: 38
  • Geschlecht:Männlich
  • Wohnort:C:\Home
  • Interessen:Computer, Feuerwehr, Sport

geschrieben 21. November 2015 - 19:07

:blink: Ich möchte am Ende in der Ausgabe jede Zeile/Spalte der Tabelle berichte haben und zusätzlich eine Zeile der Tabelle bilder, die mit der id der Tabelle berichte übereinstimmt, ansonsten null.

Oder in Worten: Alle Berichte und zu jedem Bericht ein Bild (oder null, wenn keines vorhanden).

Wenn ich jetzt die Abfrage so mache, wie von dir beschrieben, bekomme ich nur die Zeilen, die auch eine passende Zeile in der Tabelle bilder haben. Und da dann auch noch alle Bilder...


BTW: Warum nicht SELECT * ... und GROUP BY ? Die Ausgabe, die ich bekomme ist quasi genau das, was ich haben will :upsidedown:
0

#6 Mitglied ist offline   RalphS 

  • Gruppe: VIP Mitglieder
  • Beiträge: 8.895
  • Beigetreten: 20. Juli 07
  • Reputation: 1.126
  • Geschlecht:Männlich
  • Wohnort:Zuhause
  • Interessen:Ja

geschrieben 21. November 2015 - 21:55

Ja. Dann wär das ein LEFT JOIN und dieser andersherum (bezogen auf das was ich oben umrissen hatte). Sorry, hattest Du auch selber so geschrieben.

Was GROUP BY angeht, schaun wir uns mal eben diese beiden Beispiele an (und vergessen MySQL's Möglichkeiten):

Ad 1:
SELECT a.stadt,a.plz,AVG(p.alter) FROM adressen AS a JOIN personen AS p ON (a.id=p.addresse) GROUP BY a.stadt,a.plz;



Ad 2:
SELECT a.stadt,a.plz,p.alter FROM adressen AS a JOIN personen AS p ON (a.id=p.addresse) GROUP BY a.stadt,a.plz;



Was passiert da?

(1) verknüpft Personen mit ihren Adressen und zeigt das Durchschnittsalter aller Personen in nach PLZ unterteilten Städten: Wir erfahren so zum Beispiel, daß in Berlin-10210 das Durchschnittsalter 25 ist und in Berlin-12077 49. Die gruppierten Spalten in GROUP BY) tauchen dazu alle in SELECT auf; der Rest aggregiert (hier: per AVG()). Man könnte auch noch ein COUNT(name) oder wegen mir sogar ein COUNT(DISTINCT name) an die SELECT-Klausel dranhängen; dann bekäme man halt zusätzlich die Anzahl der dort gemeldeten Personen bzw wieviele unterschiedlich heißende Personen da jeweils wohnen.

In (2) auf der anderen Seite ist das nicht so. Hier wird zwar auch nach stadt und plz gruppiert... aber das Alter wird nicht per n:1 auf einen Skalar abgebildet. Das ist (außer für MySQL) eine unzulässige Anfrage, aber auch dort ist es semantischer Blödsinn. Letztlich hieße die Abfrage hier: gib mir das Alter nach Stadt und PLZ gruppiert; aber, WAS für ein Alter und wie und wo und überhaupt... das fehlt. Also eben jene Aggregatfunktion.

MySQL spuckt hier "irgendwas" aus. Dieses Ergebnis ist allerdings undefiniert. Da steht halt "irgendwas" da.
"If you give a man a fish he is hungry again in an hour. If you teach him to catch a fish you do him a good turn."-- Anne Isabella Thackeray Ritchie

Eingefügtes Bild
Eingefügtes Bild
1

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0