2016-07-13 87 views
1

我有以下SQL查詢:從連接表僅當記錄存在

SELECT 
Customers.CustomerName AS FullName, 
Customers.Id AS CustomerId, 
Customers.UserRoleId AS UserRoleId, 
Customers.Email AS Email, 
IFNULL(Customers.StudentId, '') AS CustomersStudentId, 
IFNULL(Customers.MagentoId, '') AS MagentoId, 

Sections.Id AS SectionId, 
Sections.SectionNumber AS SectionNumber, 
Sections.SectionName AS SectionName, 

Courses.Id AS CourseId, 
IFNULL(Courses.CourseName, '') AS CourseName, 
IFNULL(Courses.CourseNumber,'') AS CourseNumber, 
IFNULL(Courses.CourseDepartment, '') AS CourseDepartment, 
IFNULL(Courses.Notes, '') AS CourseNotes, 
IFNULL(Courses.Year, '') AS CourseYear, 
IFNULL(Courses.CourseType, '') AS CourseType, 

StudentsCourses.Id AS StudentsCoursesId, 
IFNULL(StudentsCourses.StudentId, '') AS StudentsCoursesStudentId, 

IFNULL(SiteProfile.StudentIdField, '') AS StudentIdField, 
IFNULL(SiteProfile.SchoolEmailDomain, '') AS SchoolEmailDomain, 

IFNULL(Orders.Id, '') AS OrderId 

FROM Customers 
    LEFT JOIN StudentsCourses ON Customers.Id = StudentsCourses.CustomerId 
    LEFT JOIN Sections ON StudentsCourses.SectionId = Sections.Id 
    LEFT JOIN Courses ON StudentsCourses.CourseId = Courses.Id 
    LEFT JOIN BooksCourses ON Courses.Id = BooksCourses.CourseId 
    LEFT JOIN Products ON BooksCourses.ISBN = Products.ISBN 
    LEFT JOIN EbookVendors ON Products.EbookVendorId = EbookVendors.Id 
    LEFT JOIN Orders ON Customers.Id = Orders.CustomerId 
    LEFT JOIN SiteProfile ON Courses.SchoolCode = SiteProfile.SchoolCode 

WHERE Customers.Id <> 10 
    AND StudentsCourses.SectionId IS NOT NULL 
    AND StudentsCourses.Delete <> 2 
    AND Courses.SchoolCode = '{$criteria["school_code"]}' 
    AND Courses.Year = {$criteria["year"]} 
    AND Courses.CourseType LIKE '{$criteria["term"]}' 

記錄會一直存在於Customers表。但是有時在任何其他連接的表中都不會有關聯的記錄。

如何修改查詢,以便在Customers表中只有記錄時,附加的SELECTWHERE子句不會中斷結果?

編輯:

當記錄只在Customers存在,我希望這個紀錄,我想WHERE條款,不屬於該Customers表被忽略。

如果記錄存在於連接表中,我希望與該連接表有關的WHERE子句起作用。

+0

解釋得更好...請....只需要客戶和其他人表之間匹配的結果,或者您希望兩者都有....別名匹配結果和客戶與其他表之間不匹配的結果? – scaisEdge

+0

更加清晰地編輯 – LXXIII

+1

將不在客戶表中的記錄上的連接限制批評移至連接。例如:'LEFT JOIN StudentsCourses ON Customers.Id = StudentsCourses.CustomerId and StudentsCourses.SectionId IS NOT NULL AND St​​udentsCourses.Delete <> 2'限制應用於連接之前,因此在與studentsCourses的連接爲空時保留客戶記錄。在使用外部連接時,大部分時間都需要在連接之前執行。或者你必須像其他人在下面的答案中所做的那樣解決空值問題。 – xQbert

回答

1

您需要更改where語句來處理空值。像這樣

WHERE Customers.Id <> 10 
    -- AND StudentsCourses.SectionId IS NOT NULL 
    AND COALESCE(StudentsCourses.Delete,0) <> 2 
    AND COALESCE(Courses.SchoolCode,'{$criteria["school_code"]}') = '{$criteria["school_code"]}' 
    AND COALESCE(Courses.Year,{$criteria["year"]}) = {$criteria["year"]} 
    AND (Courses.CourseType is null or Courses.CourseType LIKE '{$criteria["term"]}') 

當你離開加盟和值不存在,你將有空這些項目 - 仍然看你需要沒有你的where語句篩選出這些項目的行。

還有另一種方法可以將標準放入連接中。因此,例如課程類型應該是這樣的:

LEFT JOIN Courses ON StudentsCourses.CourseId = Courses.Id and Courses.CourseType LIKE '{$criteria["term"]}' 

如果你這樣做,那麼你就不需要過濾器添加到哪裏 - 這將只適用於加入,將返回null了表列如果聯接不存在。

+0

太棒了。這兩個答案都向我展示了SQL可能帶來的新東西。我會嘗試他們,並回來! – LXXIII

+0

@LXXIII - 很好!祝你好運。 – Hogan

1

當你離開加盟,你會得到在其中有沒有相應的「正確」的記錄中的字段NULL值,所以你要考慮的是:

WHERE Customers.Id <> 10 
    -- AND StudentsCourses.SectionId IS NOT NULL 
    AND (StudentsCourses.Delete <> 2 OR StudentsCourses.Delete IS NULL) 
    AND (Courses.SchoolCode = '{$criteria["school_code"]}' OR Courses.SchoolCode IS NULL) 
    AND (Courses.Year = {$criteria["year"]} OR Courses.Year IS NULL) 
    AND (Courses.CourseType LIKE '{$criteria["term"]}' OR Courses.CourseType IS NULL) 
+0

如果'StudentsCourses.Delete'爲'null',則記錄可能存在,但Delete標誌未被設置。我希望在那種情況下顯示該記錄。 – LXXIII

+1

@LXXII - 就像在我的例子中,這將顯示該記錄。 – Hogan

1

都錯了。你不能有一個返回兩個不同形式的元組的查詢:如果存在這些列,那麼這些列將存在,但是如果存在這些列的話,那麼這些列就存在。一個查詢,一個形狀。

我們已經嚴厲地說過,讓我們放鬆一下。

只要做一個外部連接,並且如果要連接的數據不存在(=找不到),NULL值將會靜靜地,無痛地填充到指定的列中。 「填充」是一個更有趣的詞。

+0

我認爲你是對的,因爲當我成功地讓查詢按照預期工作時,我最終得到了兩個條目。一個學生將會出現他們的每門課程,但是隨後會有一個額外的入口以'NULL'作爲課程返回。我最終分成兩個查詢... – LXXIII