SQL数据库 - 加入,但带有空值

时间:2015-04-07 14:52:30

标签: sql sql-server-2008 join left-join

我在使用以下视图时遇到问题(使用SQL Server 2008)。基本上,我有三个表 - tbl_PhysicalAsset(PA),tbl_Operations(OP)和tbl_Schedules(SC)。 PA中的一个记录涉及OP中的许多记录,而SC中的一个记录涉及SC中的许多记录。 PA和OP真的无关紧要,但是SC给我带来了问题。

我正在编写一个查询,显示SC的最大完成日期(基本上是通过对与OP相关的字段进行分组,以及完成日期的最大值),这是公平的。我还必须尝试解决问题"来自SC表的列(varchar),以防出现问题。这就是它倒塌的地方 - 南卡罗来纳州的一些事情将没有完成日期"填写(即它将为null),但我们仍然需要显示信息。

以下是我要去的地方:

SELECT TOP (100) PERCENT 
   dbo.tbl_PhysicalAsset.FKID_Contract, dbo.tbl_PhysicalAsset.MyLevel, 
   dbo.tbl_PhysicalAsset.L1_Name, dbo.tbl_PhysicalAsset.L2_Name, 
   dbo.tbl_PhysicalAsset.L3_Name, s1.FKID_Operation, 
   dbo.tbl_PhysicalAsset.Deleted AS Del1, 
   dbo.tbl_Operations.Deleted AS Del2, s1.Deleted AS Del3, 
   s1.SchedDone, s1.Issues
FROM         
   dbo.tbl_Schedules AS s1 
INNER JOIN
   dbo.tbl_Operations 
INNER JOIN
   dbo.tbl_PhysicalAsset ON dbo.tbl_Operations.FKID_PhysicalAsset = dbo.tbl_PhysicalAsset.PKID_PhysicalAsset 
INNER JOIN
   (SELECT     
       MAX(SchedDone) AS SchedDone, FKID_Operation
    FROM 
       dbo.tbl_Schedules
    GROUP BY 
       FKID_Operation) AS s2 ON dbo.tbl_Operations.PKID_Operation = s2.FKID_Operation ON s1.FKID_Operation = s2.FKID_Operation AND s1.SchedDone = s2.SchedDone
WHERE     
    (dbo.tbl_PhysicalAsset.FKID_Contract = 6) 
    AND (dbo.tbl_PhysicalAsset.MyLevel = 3) 
    AND (s1.FKID_Operation IS NOT NULL) 
    AND (dbo.tbl_PhysicalAsset.Deleted = 0) 
    AND (dbo.tbl_Operations.Deleted = 0) 
    AND (s1.Deleted = 0)
ORDER BY 
    dbo.tbl_PhysicalAsset.L1_Name, dbo.tbl_PhysicalAsset.L2_Name, 
    dbo.tbl_PhysicalAsset.L3_Name

正如我所说,如果记录缺少最大完成日期,那么有关它的所有信息都不会出现。

我尝试过使用左连接(甚至是右连接),但这没有区别(并且SQL Server通常会尝试提供帮助并使它们成为外连接)。

2 个答案:

答案 0 :(得分:1)

立即尝试....

SELECT PA.FKID_Contract
    , PA.MyLevel
    , PA.L1_Name
    , PA.L2_Name
    , PA.L3_Name
    , s1.FKID_Operation
    , PA.Deleted AS Del1
    , OPS.Deleted AS Del2
    , s1.Deleted AS Del3
    , s1.SchedDone
    , s1.Issues
FROM dbo.tbl_Schedules AS s1 
INNER JOIN dbo.tbl_Operations    OPS ON OPS.PKID_Operation = s1.FKID_Operation 
INNER JOIN dbo.tbl_PhysicalAsset PA  ON OPS.FKID_PhysicalAsset = PA.PKID_PhysicalAsset 
INNER JOIN 
           (SELECT  MAX(SchedDone) AS SchedDone, FKID_Operation
           FROM     dbo.tbl_Schedules
           GROUP BY FKID_Operation) AS s2 
           ON  s1.FKID_Operation = s2.FKID_Operation 
           AND s1.SchedDone = s2.SchedDone
WHERE (PA.FKID_Contract = 6) 
AND   (PA.MyLevel = 3) 
AND   (s1.FKID_Operation IS NOT NULL) 
AND   (PA.Deleted = 0) 
AND   (OPS.Deleted = 0) 
AND    (s1.Deleted = 0)
ORDER BY PA.L1_Name, PA.L2_Name, PA.L3_Name

答案 1 :(得分:0)

好的,这是我的坏事。我的一些删除字段出错了。事实证明,最初的解决方案非常适合我,并且我正在寻找在Deleted列中包含False的任何内容(在我的情况下,s1)。但是,我没有想到,如果找不到记录,它当然不会有错误。所以我把我正在检查删除的时间表的表移到了s2并且只使用了Schedules表:

SELECT TOP (100) PERCENT dbo.tbl_PhysicalAsset.FKID_Contract, dbo.tbl_PhysicalAsset.MyLevel, dbo.tbl_PhysicalAsset.L1_Name, dbo.tbl_PhysicalAsset.L2_Name, 
                  dbo.tbl_PhysicalAsset.L3_Name, dbo.tbl_PhysicalAsset.Deleted AS Del1, dbo.tbl_Operations.Deleted AS Del2, s2.SchedDone, s2.Deleted, tbl_Schedules_1.Issues, 
                  tbl_Schedules_1.Deleted AS Expr1
FROM dbo.tbl_Operations INNER JOIN
                  dbo.tbl_PhysicalAsset ON dbo.tbl_Operations.FKID_PhysicalAsset = dbo.tbl_PhysicalAsset.PKID_PhysicalAsset INNER JOIN
                      (SELECT     MAX(SchedDone) AS SchedDone, FKID_Operation, Deleted
                        FROM          dbo.tbl_Schedules
                        GROUP BY FKID_Operation, Deleted) AS s2 ON dbo.tbl_Operations.PKID_Operation = s2.FKID_Operation LEFT OUTER JOIN
                  dbo.tbl_Schedules AS tbl_Schedules_1 ON s2.SchedDone = tbl_Schedules_1.SchedDone AND s2.FKID_Operation = tbl_Schedules_1.FKID_Operation
WHERE (dbo.tbl_PhysicalAsset.FKID_Contract = 6) AND (dbo.tbl_PhysicalAsset.MyLevel = 3) AND (dbo.tbl_PhysicalAsset.Deleted = 0) AND (dbo.tbl_Operations.Deleted = 0) 
                  AND (s2.Deleted = 0)
ORDER BY dbo.tbl_PhysicalAsset.L1_Name, dbo.tbl_PhysicalAsset.L2_Name, dbo.tbl_PhysicalAsset.L3_Name