Narses - Do 20.05.10 22:53
Titel: JOIN-Problem: Bestimmte Selektion sicherstellen
Moin!
Ich habe da mal wieder ein (MySQL-)Problem, bei dem ihr mir sicher helfen könnt: ;)
Es gibt eine User-Tabelle, die ein paar Felder hat, hier reichen zunächstmal 2:
tuser.id: auotinc
tuser.email: Email-Adresse
etc.pp.
Dann gibt es eine Vorgangs-Tabelle:
tincident.id: autoinc
tincident.name: Vorgang
tincident.assigned: Benutzer, der dafür zuständig ist
etc.pp.
Und es gibt noch eine Nachrichten-Marker-Tabelle, die Benutzer markiert, die zu einem bestimmten Vorgang benachrichtigt werden wollen:
tnotify.id: autoinc
tnotify.incident_id: Vorgangs-Nr.
tnotify.user_id: User-Nr.
Sagen wir mal, der Vorgang Nr. 123 wird geändert, die Benutzer sollen benachrichtigt werden. An sich keine große Sache:
SQL-Anweisung
1: 2: 3:
| SELECT tuser.email FROM tnotify LEFT JOIN tuser ON tnotify.user_id = tuser.id WHERE tnotify.incident_id = 123 |
Liefert brav, was es soll. :) (In der Praxis hole ich natürlich noch ein paar mehr Felder aus der User-Tabelle, nicht nur die Email)
Jetzt das "Problem": :hair:
Am Vorgang ist auch ein Benutzer hinterlegt, der für das Ding zuständig ist. Dieser soll immer eine Nachricht bekommen, egal ob er sie wünscht oder nicht. :P Gut, kann man mit einem UNION dranhängen, dann habe ich aber ggfs. zwei mal eine Nachricht gesendet, weil der Bearbeiter ja auch schon in der ersten Ergebnismenge enthalten sein könnte. :|
Wie knote ich jetzt diesen Bearbeiter in die Ergebnismenge rein, ohne diesen im Zweifel doppelt zu haben? :think: :nixweiss:
cu
Narses
//EDIT: Ich bemerke gerade beim Basteln an der Abfrage, dass UNION offenbar nur die Auswahl erweitert, der Datensatz kommt in der Ergebnismenge nicht doppelt vor, wenn ich das so abfrage: (User 3 hat einen Eintrag in tnotify und ist Bearbeiter)
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7:
| SELECT tuser.email FROM tnotify LEFT JOIN tuser ON tnotify.user_id = tuser.id WHERE tnotify.incident_id = 123 UNION SELECT tuser.email FROM tuser WHERE tuser.id = 3 |
Kann das sein? :gruebel: :?
//EDIT2:
| MySQL-Hilfe zu UNION hat folgendes geschrieben: |
| Geben Sie das Schlüsselwort ALL an, dann enthält das Ergebnis alle passenden Datensätze aus allen SELECT-Anweisungen. Wenn Sie DISTINCT angeben, werden doppelte Datensätze aus dem Ergebnis entfernt. Wird kein Schlüsselwort benutzt, dann entspricht das Standardverhalten dem von DISTINCT (Entfernung doppelter Datensätze). |
Scheint also per Default zu passen, ist ja witzig... :?
Schonmal jemand an dieser Stelle Erfahrungen gesammelt? Probleme gehabt? :nixweiss:
Narses - Fr 21.05.10 12:34
Moin!
MarkusB hat folgendes geschrieben : |
| vielleicht so: |
Das habe ich im Wesentlichen auch erst probiert, aber das scheint UNION schon direkt zu filtern (s.o.). :idea:
BenBE hat folgendes geschrieben : |
| Ohne USES auch so: |
Du meinst UNION? ;)
BenBE hat folgendes geschrieben : |
SQL-Anweisung 1: 2: 3:
| SELECT tuser.email FROM tincident, tuser LEFT JOIN tnotify ON (tnotify.user_id = tuser.id) OR (tuser.id = tincident.assigned) WHERE tincident.id = tnotify.incident_id AND tnotify.incident_id = 123 | |
Das sieht spannend aus, muss ich mir gleich mal genauer reinziehen... :les:
BenBE hat folgendes geschrieben : |
| Merke: Die LEFT-JOIN-Syntax ist im Wesentlichen syntaktischer Zucker :P |
Sieht aber hübsch aus... :schmoll:
BenBE hat folgendes geschrieben : |
| Oder halt ohne JOIN einfach über die WHERE abfackeln. |
:?:
cu
Narses
Narses - Sa 22.05.10 10:16
Moin!
BenBE hat folgendes geschrieben : |
k. |
Klappt nicht:
| MySQL-Server hat folgendes geschrieben: |
| #1054 - Unknown column 'tincident.assigned' in 'on clause' |
:|
BenBE hat folgendes geschrieben : |
SQL-Anweisung 1: 2: 3: 4: 5:
| SELECT tuser.email FROM tincident, tuser, tnotify WHERE ((tnotify.user_id = tuser.id) OR (tuser.id = tincident.assigned)) AND (tincident.id = tnotify.incident_id) AND (tnotify.incident_id = 123) | |
Liefert den zuständigen Menschen doppelt in der Ergebnismenge.
Scheint noch etwas buggy, oder? :zwinker:
Fazit: Das UNION oben tut´s, wenn kein überragend guter Vorschlag mehr kommt, bleibt´s auch so. ;)
cu
Narses
Narses - So 23.05.10 13:45
Moin!
MarkusB hat folgendes geschrieben : |
| Noch ein Versuch: |
Danke für deinen Einsatz. :zustimm: Aber lies doch nochmal bitte meinen ersten Beitrag, besonders die beiden Nachträge. Im Wesentlichen habe ich es jetzt schon so, nur dass man den zuständigen Menschen nicht aus der ersten Menge rausnehmen muss, dass macht das UNION schon defaultmäßig. ;) :idea:
BenBE hat folgendes geschrieben : |
| @Narses: Du hättest auch bei meiner Variante einfach nur nach dem Select ein DISTINCT schreiben brauchen; obwohl mich das etwas wundert, woher der Doppelte dort kommt. |
Ja, das ist schon klar. ;) Den Preis gibt´s aber nur für eine Lösung OHNE UNION
und OHNE DISTINCT (also für eine "flache" Abfrage). :mrgreen:
cu
Narses