2016-07-13 4 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 таблицы. Но иногда в любой из других объединенных таблиц не будет связанных записей.

Как изменить запрос, чтобы дополнительные статьи SELECT и WHERE не нарушали результаты, если в таблице Customers есть только записи?

EDIT:

Если запись существует только в Customers, я хочу эту запись, и я хочу, чтобы WHERE положения, которые не относятся к Customers таблицы следует игнорировать.

Если запись существует в объединенной таблице, я хочу, чтобы статья WHERE, относящаяся к этой объединенной таблице, работала.

+0

объясните лучше ... пожалуйста .... вы хотите получить только результат, который соответствует таблице клиентов и других, или вы хотите, чтобы оба были. Alias ​​результат для соответствия и для несовпадения между клиентами и другими таблицами? – scaisEdge

+0

Отредактировано с большей ясностью – LXXIII

+1

Переместить ограничение ограничения соединения на записи, не входящие в таблицу клиентов, в соединения. Пример: 'LEFT JOIN StudentsCourses ON Customers.Id = StudentsCourses.CustomerId AND StudentsCourses.SectionId NOT NULL AND StudentsCourses.Delete <> 2' Предел применяется до объединения, таким образом, сохраняя записи клиентов, когда соединение с учениками должно быть недействительным , В большинстве случаев, когда используются внешние соединения, критерии присоединения должны быть выполнены до объединения. ИЛИ вы должны учитывать нули, как это делали другие в ответах ниже. – 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"]}') 

Когда вы оставили присоединиться и значение не существует, вы будете иметь нуль для этих элементов - по-прежнему видеть строку, которую нужно не ваш, где оператор отфильтровывать эти элементы.

Существует другой способ сделать это, чтобы поставить критерии в соединениях. Так что для типа пример, конечно, будет выглядеть следующим образом:

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

Если вы сделаете это, то вам не нужно, чтобы добавить фильтр к где - он будет применяться только к присоединиться и возвратит нуль для столбцов таблицы, если соединение не существует.

+0

Удивительный. Оба ответа показали мне новые вещи, которые возможны с SQL. Я попробую их и вернусь! – LXXIII

+0

@ LXXIII - приятно! Удачи. – Hogan

1

Когда вы ушли присоединиться, вы собираетесь получить NULLs в тех областях, для которых нет соответствующего «право» запись, так что вы должны учитывать, что:

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

Смежные вопросы