2017-03-29 7 views
0

Ich weiß zu schätzen, dass es viele Tutorials und Beispiele gibt, die JOIN-Konzepte erklären - aber ich habe Mühe, die Beispiele auf mein spezifisches Szenario anzuwenden. Ich würde mich über einige Hilfe freuen, und wenn es nicht zu viel verlangt ist - eine Aufschlüsselung dessen, was in der Lösung vor sich geht, um die gewünschten Ergebnisse zu erzielen.Auswählen von Zeilen aus 3 Tabellen

3 Tabellen: Benutzer, Assessments, assessment_log.

Benutzer

+--------+------+------+-----------+----------+-----------+-------+--------+-----------+---------------+------+----------+ 
| UserID | User | Pass | FirstName | LastName | LastLogin | Email | Mobile | Kenitalla | AccountStatus | Role | Operator | 
+--------+------+------+-----------+----------+-----------+-------+--------+-----------+---------------+------+----------+ 

Einschätzungen

+--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+ 
| AssessmentID | Name | Criteria1 | Criteria2 | Criteria3 | Criteria4 | Criteria5 | RoleRequired | Required | Renewal | Operator | 
+--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+ 

assessment_logs

+-----------------+------+----------------+------------+--------+-----------+----------+----------+----------+----------+----------+----------+---------+---------------+---------+ 
| AssessmentLogID | Date | AssessmentName | AssessedBy | UserID | StaffName | Comments | Verdict1 | Verdict2 | Verdict3 | Verdict4 | Verdict5 | Verdict | RenewalPeriod | NextDue | 
+-----------------+------+----------------+------------+--------+-----------+----------+----------+----------+----------+----------+----------+---------+---------------+---------+ 

Wenn ein Benutzer eine Beurteilung erfolgt, geht ein Eintrag in die assessment_log in. Einige Bewertungen sind erforderlich (wahr oder falsch in Spalte Erforderlich), da einige optional sind. In der Spalte RoleRequired ist festgelegt, für welche Benutzerrolle die Bewertung erforderlich ist.

Ich möchte eine Liste der Benutzer und Bewertungen erstellen, die sie noch bestehen müssen. Die Bewertungen müssen erforderlich sein und die erforderliche Rolle muss mit der Benutzerrolle übereinstimmen. Ein Fehlen eines Eintrags in den assessment_log mit einem "Pass" in der Spalte "Verdict" zeigt an, dass die Bewertung noch nicht bestanden wurde.

Im Klar sprechen, bin ich für eine Abfrage suchen, das folgende Ergebnis erzielen:

+------------------+-----------------+----------------+ 
| assessments.Name | users.FirstName | users.LastName | 
+------------------+-----------------+----------------+ 

Wo die Bewertung erforderlich ist (Erforderlich gleich true), entspricht die RequiredRole die users.Role Spalte, und es ist kein Eintrag im Assessments_log für die Bewertung, wo die Spalte "Verdict" einen "Pass" -Wert enthält.

Bitte lassen Sie mich wissen, wenn weitere Klärung erforderlich ist.

Vielen Dank im Voraus!

Antwort

0

Ich würde vorschlagen, eine LINKE VERBINDUNG zu verwenden.

Zunächst erstellen wir ein Produkt aus Bewertungen und Benutzern, das für jeden Benutzer alle Bewertungen enthält, die für seine Rolle erforderlich sind.

Dann überprüft ein LINKER JOIN, ob diese Bewertungen bestanden wurden.

SELECT ... 
FROM 
    users u 
    JOIN assessments a ON (a.RoleRequired = u.Role) 
    LEFT JOIN assessment_logs al ON (
      al.AssessmentID = a.AssessmentID 
     AND al.UserID = u.UserID 
     AND al.Verdict='Pass' 
    ) 

WHERE 
     a.required 
    AND al.UserID IS NULL 
+0

Das scheint mir das Ergebnis, das ich dafür danken Ihnen erwar- macht! Ich werde LEFT JOINs genauer betrachten ... selbst mit Ihrem klaren Beispiel und meiner Erklärung habe ich Probleme mit dem Konzept. Es scheint, als ob Sie zusätzliche Kriterien auf den LINKEN JOIN verkettet haben - die Beispiele, die ich lese, beziehen sich auf das Auswählen von Zeilen aus einer Tabelle und das Zurückgeben von Zeilen aus der zweiten Tabelle (rechts), wo Zeilen übereinstimmen. Können Sie die "AND al.UserID = u.UserID" und "AND al.Verdikt = 'Pass' "Teil der Abfrage? –

+0

http://www.mysqltutorial.org/mysql-left-join.aspx Es funktioniert genauso wie ein normaler (innerer) Join, außer wenn keine Zeile die Bedingungen in der übereinstimmt Wenn JOIN ON() gefunden wird, wird stattdessen eine Dummy-NULL-Zeile zurückgegeben.So wird ein LINKER JOIN bON (cond) WHERE b.id IS NULL die Zeilen in a zurückgeben, wo keine Zeile in b übereinstimmt (cond). Ich habs? – peufeu

0

Ihre Attributnamen sind inkonsistent zwischen Tabellen und, obwohl ich keine doppelten Namen nicht sehen, es ist wohl nur eine Frage der Zeit, bevor Sie das tun, so schlage ich vor, Sie dieses Problem zu beheben.

In der Zwischenzeit ist hier, wie die Spalten on the fly, um benennen Sie die Join-Syntax zu vereinfachen:

SELECT AssessmentName, UserLastName, UserFirstName 
    FROM (SELECT FirstName AS UserFirstName, Lastname AS UserLastName, Role 
      FROM users) u 
     NATURAL JOIN 
     { SELECT Name AS AssessmentName, RoleRequired AS Role 
      FROM assessments 
      WHERE Required) a 
     NATURAL JOIN 
     (SELECT AssessmentName 
      FROM assessment_logs 
      WHERE Verdict = 'Pass') l; 
Verwandte Themen