2017-03-29 87 views
0

我很欣賞有很多教程和示例解釋JOIN概念,但我很努力將示例應用到我的特定場景。我希望得到一些幫助,如果沒有太多要求,可以分解解決方案中發生的事情,以達到預期的結果。從3個表中選擇行

3表:用戶,評估,評估日誌。

用戶

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

評估

+--------------+------+-----------+-----------+-----------+-----------+-----------+--------------+----------+---------+----------+ 
| 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 | 
+-----------------+------+----------------+------------+--------+-----------+----------+----------+----------+----------+----------+----------+---------+---------------+---------+ 

當用戶需要進行評估,一個條目變成到assessment_log。一些評估是必需的(在必填列中爲true或false),其中一些是可選的。 RoleRequired列規定評估所需的用戶角色。

我想生成一個用戶列表和他們尚未通過的評估。評估必須是必需的,所需角色必須與用戶角色相匹配。在判決欄中沒有進入assessment_log並帶有「通行證」表示評估尚未通過。

在普通的說話,我要尋找一個查詢,將實現以下目的:

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

如果需要評估(必需等於真),RequiredRole的users.Role列相匹配,並有在Verdict列中持有「通過」值的評估的評估日誌中沒有條目。

請讓我知道,如果需要進一步澄清。

在此先感謝!

回答

0

我建議使用LEFT JOIN。

首先,我們生成評估和用戶的交叉產品,其中包含每個用戶的角色所需的所有評估。

然後,LEFT JOIN檢查這些評估是否通過。

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

這似乎給我,結果我expect-向你表示感謝!我會更詳細地研究LEFT JOIN ...即使有你清晰的例子和解釋,我也在爲這個概念而努力。 看起來好像您已將其他條件鏈接到LEFT JOIN上 - 我讀取的示例指的是從一個表中選擇行並從行中匹配的第二個表(右側)返回行。 你能解釋一下「AND al.UserID = u.UserID」和「AND al。Verdict ='Pass'「部分查詢? –

+0

http://www.mysqltutorial.org/mysql-left-join.aspx它與普通(內部)連接相同,除非沒有匹配條件的行找到JOIN ON()後,將返回一個虛擬的全NULL行。因此,一個LEFT JOIN b ON(cond)WHERE b.id IS NULL將返回b行中沒有行匹配的行(cond)。得到它了? – peufeu

0

你的屬性名錶之間不一致的,雖然我沒有看到任何重複的名稱,它可能只是在此之前一個時間的問題,所以我建議你解決這個問題。

在此期間,這裏是如何重新命名,以簡化聯接語法上飛列:

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;