仅当记录存在时才从联接表中选择

时间:2016-07-13 17:45:24

标签: mysql sql

我有以下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表中只有记录时,如何修改查询以便其他WHERECustomers子句不会破坏结果?

编辑:

当记录仅存在于Customers中时,我想要该记录,并且我希望忽略与WHERE表无关的Customers子句。

如果记录存在于连接表中,我希望与该连接表有关的WHERE子句起作用。

3 个答案:

答案 0 :(得分: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"]}')

当你离开连接并且该值不存在时,这些项目将为null - 仍然会看到你需要没有where语句的行过滤掉那些项目。

还有另一种方法可以将标准放在连接中。例如,课程类型如下所示:

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

如果你这样做,那么你不需要将过滤器添加到where - 它只会应用于连接,如果连接不存在,将为表列返回null。

答案 1 :(得分:1)

当你离开加入时,你将在没有相应的&#34;右边&#34;的字段中获得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)

答案 2 :(得分:1)

两个都错了。您不能有一个返回两个不同形状的元组的查询:如果存在这些列,则从这里开始,但如果存在帽子,那么这些列来自此处和那里。一个查询,一个形状。

严厉地说,让我们放松一下。

只做一个外连接,如果要连接的数据不存在(=无法找到),NULL值将无声地,无痛地填充到指定的列中。 “人口稠密”就是一个更加有趣的词。