【问题标题】:SQL database - joining, but with nullsSQL 数据库 - 加入,但有空值
【发布时间】:2015-06-12 05:26:31
【问题描述】:

以下视图有问题(使用 SQL Server 2008)。基本上,我有三张桌子 - tbl_PhysicalAsset (PA)、tbl_Operations (OP) 和 tbl_Schedules (SC)。 PA 中的一条记录与 OP 中的许多记录有关,OP 中的一条记录与 SC 中的许多记录有关。 PA 和 OP 在这里真的无关紧要,但是 SC 给我带来了问题。

我正在编写一个查询,它显示来自 SC 的最大完成日期(基本上是通过对与 OP 相关的字段和完成日期的最大值进行分组来完成),这很公平。我还必须尝试从 SC 表中获取“问题”列(varchar),以防出现问题。这就是它失败的地方——SC 中的一些东西不会填写“完成日期”(即它将为空),但我们仍然需要显示信息。

以下是我要去的地方:

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 通常会尝试提供帮助并将它们设为外连接)。

【问题讨论】:

  • 您的查询中有语法错误。您有一个 INNER JOIN 没有 ON 子句,聚合子查询后有两个 ON 子句。您是否删除了括号?

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


【解决方案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

【讨论】:

  • 感谢更简洁的代码 - 但仍然无法正常工作。但是,这是一个不错的方法。
【解决方案2】:

好吧,这是我的错。我在一些已删除的字段上犯了一个错误。原来,最初的解决方案非常准确,我正在寻找在 Deleted 列中包含 False 的任何内容(在我的例子中,s1)。但是,我没有想到,如果一个记录找不到,它当然不会有一个False。因此,我将要检查已删除计划的表移至 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

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2013-04-17
    • 1970-01-01
    相关资源
    最近更新 更多