2016-07-13 9 views
1

existiert Ich habe die folgende SQL-Abfrage:nur, wenn Datensatz

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"]}' 

Records existieren immer in der Customers Tabelle. Aber manchmal gibt es keine verknüpften Datensätze in den anderen verbundenen Tabellen.

Wie ändere ich die Abfrage, so dass die zusätzlichen SELECT und WHERE Klauseln nicht die Ergebnisse brechen, wenn nur Datensätze in der Customers Tabelle sind?

EDIT:

Wenn der Datensatz nur in Customers vorhanden ist, möchte ich, dass Datensatz und ich möchte, dass die WHERE Klauseln, die dem Customers Tabelle beziehen sich nicht ignoriert werden.

Wenn der Datensatz in einer Joined-Tabelle vorhanden ist, möchte ich die WHERE-Klausel, die zu dieser verknüpften Tabelle gehört.

+0

erklären besser ... bitte .... Sie wollen nur das Ergebnis, dass die Übereinstimmung zwischen Kunden und anderen Tabelle oder Sie wollen beide .... alias das Ergebnis für die Übereinstimmung und für nicht übereinstimmen zwischen Kunden und anderen Tabellen? – scaisEdge

+0

Bearbeitet mit mehr Übersichtlichkeit – LXXIII

+1

Verschieben Sie die Join-Einschränkungs-Kriterien für Datensätze, die nicht in der Kundentabelle enthalten sind, zu den Joins. Beispiel: 'LEFT JOIN StudentsCourses ON Kunden.Id = StudentsCourses.CustomerId UND StudentsCourses.SectionId IST NICHT NULL AND StudentsCourses.Delete <> 2' Das Limit wird vor dem Join angewendet, wodurch die Kundendatensätze beibehalten werden, wenn der Join zu studentsCourses null ist . In den meisten Fällen müssen bei Verwendung von Outer-Joins die Join-Begrenzungskriterien vor dem Join ausgeführt werden. ODER Sie müssen Nullen berücksichtigen, wie andere unten in den Antworten getan haben. – xQbert

Antwort

1

Sie müssen die Where-Anweisung ändern, um mit Nullen umzugehen. Wie dies

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"]}') 

Wenn Sie Mitglied links und der Wert nicht existiert Sie für diese Elemente null haben wird - noch die Zeile sehen Sie müssen nicht Ihr, wo Anweisung die Elemente herauszufiltern.

Es gibt eine andere Möglichkeit, die Kriterien in die Joins zu setzen. So zum Beispiel Kursart würde wie folgt aussehen:

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

Wenn Sie dies tun, dann müssen Sie die Filter nicht auf den in dem hinzuzufügen - es wird nur die angewandt wird, beitreten und wird für die null zurück Tabellenspalten, wenn der Join nicht existiert.

+0

Ehrfürchtig. Beide Antworten haben mir neue Dinge gezeigt, die mit SQL möglich sind. Ich werde sie versuchen und zurückkommen! – LXXIII

+0

@LXXIII - nett! Viel Glück. – Hogan

1

Wenn Sie Mitglied links, du gehst NULLs in den Bereichen zu erhalten, für die es keine entsprechende „richtigen“ Datensatz ist, so dass Sie für dieses Konto müssen:

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

Wenn 'StudentsCourses.Delete'" null "ist, ist es möglich, dass der Datensatz existiert, aber das Löschen-Flag wurde nicht gesetzt. Ich möchte, dass dieser Datensatz in diesem Szenario angezeigt wird. – LXXIII

+1

@LXXII - genau wie in meinem Beispiel wird dies den Rekord zeigen. – Hogan

1

beide falsch. Sie können keine Abfrage haben, die zwei verschiedene Formen von Tupeln zurückgibt: diese Spalten von hier, wenn diese existieren, aber diese Spalten von hier und da, wenn sie existieren. Eine Abfrage, eine Form.

Nachdem wir streng gesagt wurden, lassen Sie uns ein wenig entspannen.

Führen Sie einfach einen Outer-Join aus, und wenn die zu verbindenden Daten nicht vorhanden sind (= nicht gefunden werden können), werden NULL-Werte automatisch in die angegebenen Spalten eingefügt. "Populated" ist ein schickeres Wort dafür.

+0

Ich denke, Sie haben recht, denn als ich die Abfrage erfolgreich zum gewünschten Ergebnis gebracht hatte, erhielt ich doppelte Einträge. Ein Schüler würde mit jedem seiner Kurse auftauchen, aber dann würde ein zusätzlicher Eintrag mit "NULL" als Kurs zurückgegeben werden. Ich habe es in zwei Fragen getrennt ... – LXXIII

Verwandte Themen