SQL 服务器:多个 table 加入一个或多个 WHERE 子句

SQL Server: Multiple table joins with one or more WHERE clauses

我是 运行 SQL 服务器,正在尝试从 CRM 应用程序连接多个表,但无法获得所需的结果。我发现这篇文章 SQL Server: Multiple table joins with a WHERE clause 包含与我正在寻找的内容接近的信息,但我也无法使用它。

我有 5 张桌子

机器Table

- MachID       Name
-   1         Mach1
-   2         Mach2
-   3         Mach3

维护Table

- MaintID       StatusCode
-   1                1
-   2                1

维护扩展Table

- MaintID      MaintName              StartDate               EndDate              MachId
-   1         Maint Test 1    2015-02-01 05:00:00.000    2015-02-03 05:00:00.000     2
-   2         Maint Test 2    2015-02-06 05:00:00.000    2015-02-09 05:00:00.000     2 

计划Table

- SchedID       StatusCode
-   1                1
-   2                1

计划延期 Table

- SchedID      SchedName              StartDate               EndDate               MachId     JobNumber
-   1         Sched Test 1    2015-01-15 05:00:00.000    2015-01-19 05:00:00.000       2        1111
-   2         Sched Test 2    2015-01-20 05:00:00.000    2015-01-23 05:00:00.000       2        2222

所以我尝试了这个查询,因为我想获得一组数据,当维护事件中有一个带有 NULL 的计划事件时,这些数据将显示一个行项目,同样地,当有一个时显示维护事件在计划事件中为 NULL。如果两者只有一个,则只显示没有内容的 NULL 项。

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '1/05/15'
SET @EndDate = '5/2/15'
SELECT
     mn.name AS MachineName
    ,se.Schedname AS SchedName
    ,me.Maintname AS MaintName
    ,se.StartDate AS SchStartDate
    ,se.EndDate AS SchEndDate
    ,se.JobNumber
    ,sb.statuscode AS SchStat
    ,mb.statuscode AS MaintStat
    ,me.StartDate AS MaintStartDate
    ,me.EndDate AS MaintEndDate
FROM [machines] AS mn
INNER JOIN [MaintenanceExtension] AS me
ON mn.MachId = me.MachId
INNER JOIN [Maintenance] AS mb
ON me.MaintId = mb.MaintId
INNER JOIN [ScheduleExtension] as se
ON se.MachId = mn.MachId
INNER JOIN [Schedule] AS sb
ON sb.SchedId = se.SchedId
WHERE  se.StartDate between @StartDate and @EndDate

我得到的似乎包括 MaintStartDate 和 Schedule 项,反之亦然。为什么相对的列不显示 NULL?

MachineName    SchedName    MaintName             SchStartDate             SchEndDate           JobNumber     SchStat     MaintStat       MaintStartDate            MaintEndDate
   Mach2      SCH TEST 1    MAINT TEST 1       2015-01-15 05:00:00.000  2015-01-19 05:00:00.000   12345         1            1        2015-02-01 05:00:00.000   2015-02-03 05:00:00.000
   Mach2      SCH TEST 2    MAINT TEST 1       2015-01-20 05:00:00.000  2015-01-23 05:00:00.000   7894          1            1        2015-02-01 05:00:00.000   2015-02-03 05:00:00.000
   Mach2      SCH TEST 1    MAINT TEST 2       2015-01-15 05:00:00.000  2015-01-19 05:00:00.000   12345         1            1        2015-02-06 05:00:00.000   2015-02-09 05:00:00.000
   Mach2      SCH TEST 2    MAINT TEST 2       2015-01-20 05:00:00.000  2015-01-23 05:00:00.000   7894          1            1        2015-02-06 05:00:00.000   2015-02-09 05:00:00.000

我要找的是这样的:

MachineName    SchedName    MaintName             SchStartDate             SchEndDate           JobNumber     SchStat     MaintStat       MaintStartDate            MaintEndDate
   Mach2      SCH TEST 1      NULL          2015-01-15 05:00:00.000 2015-01-19 05:00:00.000       1111          1            1                NULL                    NULL
   Mach2      SCH TEST 2      NULL          2015-01-20 05:00:00.000 2015-01-23 05:00:00.000       2222          1            1                NULL                    NULL
   Mach2         NULL    MAINT TEST 1               NULL                      NULL                NULL          1            1        2015-02-01 05:00:00.000   2015-02-03 05:00:00.000
   Mach2         NULL    MAINT TEST 2               NULL                      NULL                NULL          1            1        2015-02-06 05:00:00.000   2015-02-09 05:00:00.000

INNER JOIN 表示您想要连接两个表,其中列已填充到两个表中。由于您需要具有 MaintenanceExtension 或 ScheduleExtension 的机器的所有结果,请尝试使用此尺寸。

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '1/05/15'
SET @EndDate = '5/2/15'
SELECT
     mn.name AS MachineName
    ,se.Schedname AS SchedName
    ,me.Maintname AS MaintName
    ,se.StartDate AS SchStartDate
    ,se.EndDate AS SchEndDate
    ,se.JobNumber
    ,sb.statuscode AS SchStat
    ,mb.statuscode AS MaintStat
    ,me.StartDate AS MaintStartDate
    ,me.EndDate AS MaintEndDate
FROM [machines] AS mn
LEFT JOIN [MaintenanceExtension] AS me
ON mn.MachId = me.MachId
LEFT JOIN [Maintenance] AS mb
ON me.MaintId = mb.MaintId
LEFT JOIN [ScheduleExtension] as se
ON se.MachId = mn.MachId
LEFT JOIN [Schedule] AS sb
ON sb.SchedId = se.SchedId
WHERE  se.StartDate between @StartDate and @EndDate

这将为您提供所有结果,包括既没有 MaintenanceExtension 也没有 ScheduleExtension 的机器。如果你想限制有一个或另一个的机器,那么你需要这个 where 子句。

WHERE  se.StartDate between @StartDate and @EndDate
  AND  (me.MachId IS NOT NULL OR se.MachID IS NOT NULL)

最后,如果你想排除同时拥有这两者的机器,你需要这个 where 子句。

WHERE  se.StartDate between @StartDate and @EndDate
  AND  (me.MachId IS NOT NULL OR se.MachID IS NOT NULL)
  AND  (me.MachId IS NULL OR se.MACHId IS NULL)