Mysql UNION und JOIN in einer Abfrage

Sprint

Erfahrenes Mitglied
Hallo zusammen,

ich habe zwei Tabellen, von denen die eine Reihe fest vorgegebener Prüfgruppen beinhaltet und die andere vom User noch selbst erstellte Prüfgruppen. Die werden mit UNION zusammen eingelesen.
SQL:
SELECT    g.gid, g.gtext
FROM    checkgruppen g
WHERE    g.gid = g.obergruppe
UNION
SELECT    u.gid, u.gtext
FROM    usergruppen u
WHERE    u.kdnr = '$kunde'";
Nun sollen aber noch die Sichtbarkeit der einzelnen Punkte verschiedenen Bereichen zugeordnet werden. Z.B. hat der Verkauf ja mit der Abrechnung nichts zu tun, also brauchen die den Bereich auch nicht zu sehen.

Diese Tabelle wird so aussehen:
Code:
kdnr    gid        verkauf        dispo        buchhaltung
Für die Verwaltung der Zuordnungen sollen nun alle Prüfgruppen mit den jeweiligen Bereichen aufgelistet werden. Das wäre normalerweise eine Aufgabe für JOIN, nur wie bringe ich da noch JOINs in der Abfrage unter?
 
Lösung
Unterabfragen
SQL:
SELECT ...
FROM (
        SELECT ..
        UNION SELECT ....
    ) AS A
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
Oder den JOIN auf beiden Quellen
SQL:
SELECT ...
FROM 
    table_a_1 AS A 
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
UNION SELECT ...
FROM 
    table_a_2 AS A 
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
Unterabfragen
SQL:
SELECT ...
FROM (
        SELECT ..
        UNION SELECT ....
    ) AS A
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
Oder den JOIN auf beiden Quellen
SQL:
SELECT ...
FROM 
    table_a_1 AS A 
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
UNION SELECT ...
FROM 
    table_a_2 AS A 
    LEFT JOIN TABLE_B AS B
        ON A.B_ID = B.ID
 
Zuletzt bearbeitet:
Lösung
Kannst du mal Beispieldaten (Bsp. Excel-Format) hier reinstellen?
Also Beispiel "Was steht in Checkgruppen", "Was in UserGruppen", und wie sieht das Endergebnis aus

Ich hab so ne Ahnung wie das gehen kann

EDIT: Nachtrag: im Union: Sind g.gid und u.gid eindeutig? Ich meine, kann eine u.gid schon in g.gid vorkommen? Falls ja, wer hat Vorrang
 
Zuletzt bearbeitet:
@Yaslaw
Genau das habe ich gesucht. Vielen Dank für deine Hilfe!

@Zvoni
Hab deine Nachricht gerade erst gesehen, hab aber die Lösung von Yaslaw schon umgesetzt. So sieht das jetzt fertig aus.
SQL:
SELECT g.gid, g.gtext, b.verkauf, b.buchhaltung, b.dispo, b.geschleitung, b.ausblenden
FROM checkgruppen g
LEFT JOIN bereichszuordnung b
    ON g.gid = b.gid AND b.kdnr = '$kunde'
WHERE g.gid = g.obergruppe
UNION ALL
SELECT u.gid, u.gtext, b.verkauf, b.buchhaltung, b.dispo, b.geschleitung, b.ausblenden
FROM usergruppen u
LEFT JOIN bereichszuordnung b
    ON u.gid = b.gid AND b.kdnr = '$kunde'
 
Alternative (Ich arbeite gerne mit CTE's, da ich da zusammen gehörendes besser gruppieren kann.
Kann u.U. sogar Auswirkungen auf Performance haben

Frage: Ist das '$kunde' eine PHP-Variable oder ein Parameter?
Ungetestet
SQL:
WITH
    BZ AS (SELECT gid, verkauf, buchhaltung, dispo, geschleitung, ausblenden FROM
           bereichszuordnung WHERE kdnr='$kunde'),
    UN AS (SELECT g.gid, g.gtext FROM checkgruppen g
           UNION
           SELECT u.gid, u.gtext FROM usergruppen u)

SELECT gid, gtext, verkauf, buchhaltung, dispo, geschleitung, ausblenden
FROM UN
LEFT JOIN BZ ON BZ.gid=UN.gid

Oder
SQL:
WITH
    BZ AS (SELECT kdnr, gid, verkauf, buchhaltung, dispo, geschleitung, ausblenden FROM
           bereichszuordnung),
    UN AS (SELECT g.gid, g.gtext FROM checkgruppen g
           UNION
           SELECT u.gid, u.gtext FROM usergruppen u)

SELECT gid, gtext, verkauf, buchhaltung, dispo, geschleitung, ausblenden
FROM UN
LEFT JOIN BZ ON BZ.gid=UN.gid AND BZ.kdnr='$kunde'
 
$kunde ist eine PHP Variable.

Mit CTEs hab ich noch nie gearbeitet, muß mich da erst einmal einlesen.
 
$kunde ist eine PHP Variable.
In dem Fall ist die erste Alternative zu bevorzugen, weil früher gefiltert wird.
Mit CTEs hab ich noch nie gearbeitet, muß mich da erst einmal einlesen.
Stell dir CTE's als "temp. VIEW" vor, welche aber direkter Bestandteil des SQL-Statements ist,
während man eine "echte" View im Prinzip als "virtuelle" Tabelle betrachten kann.

Eine CTE erstellt im Prinzip im Hintergrund eine VIEW, führt das Statement aus, Drop-ed am Ende dann die VIEW

Mit CTE's kann man viele lustige Sachen machen (Z.B. rekursive Aufrufe)
 
Mit "echtes" View meinst du also das, was meine Lösung darstellt?

Liest sich recht interessant. Muß ich mich mal mit beschäftigen.
 
Mit "echtes" View meinst du also das, was meine Lösung darstellt?

Liest sich recht interessant. Muß ich mich mal mit beschäftigen.
nein, ein "echtes" View ist ein "echtes" (permanentes) Objekt in einer Datenbank.
Sieht von aussen wie eine Tabelle aus, jedoch mit ein paar Einschränkungen (keine Variable, Keine Parameter und andere Dinge)
Les dich echt mal ein in die Sachen.

Ist dein Query oben z.B. etwas, was immer wiederholt aufgerufen wird, wäre es z.B. möglich anstatt meiner zweiten ( !) Alternative, die zwei CTE's BZ und UN einmal als zwei echte View's anlegen.
Dann wäre dein SQL-Statement das was in Zeile 8-10 in der zweiten Variante oben steht
 
Ist dein Query oben z.B. etwas, was immer wiederholt aufgerufen wird, wäre es z.B. möglich anstatt meiner zweiten ( !) Alternative, die zwei CTE's BZ und UN einmal als zwei echte View's anlegen.
Dann wäre dein SQL-Statement das was in Zeile 8-10 in der zweiten Variante oben steht
Nein, das wird ein Mal aufgerufen und liest dann alle Zuordnungen eines Kunden ein. Insgesamt ist das eher eine Sache, die alle paar Wochen mal gebraucht wird, wenn sich ein Kunde für diese Dienstleistung entscheidet.
 
Zurück