【问题标题】:SQL Server NULL value with inner join带有内部联接的 SQL Server NULL 值
【发布时间】:2011-08-14 04:34:54
【问题描述】:

我正在使用 C# 和 SQL Server。

看看下面的SQL:

SELECT table1.id, table1.description, table2.name, table2.surname 
FROM table1 
    INNER JOIN table2 ON table1.EmpID = table2.EmpID

这是直截了当的,工作正常。它可以很好地从 table1 表中检索数据,并且内部连接 ​​table1.empidtable2.nametable2.surname 正确。

现在,有时table1.empid 为空,而当它为空时,此 SQL 将忽略具有空值的“行”;根据标准,这很正常。

我在这里还需要获取具有空值的“行”,当table1.empid 为空时,我需要将自定义值设置为table2.nametable2.surname

我一直在玩 isnull() 但我所做的只是让它变得更糟。

有什么建议吗?

谢谢

【问题讨论】:

  • 您确实需要提供一些带有一些预期输出的示例数据。例如,当 table1.EmpID 为 Null 时,应该出现 table2 的哪些行?没有?

标签: c# sql null inner-join isnull


【解决方案1】:

您需要进行 LEFT JOIN:

SELECT table1.id, table1.description, table2.name, table2.surname FROM table1
LEFT JOIN table2 ON table1.EmpID = table2.EmpID;

【讨论】:

  • 关闭,但 table1 的值不必为空才能显示记录;如果没有具有该 empID 的 table2 记录,它仍然会出现在结果中。此外,table2 值将始终返回 null,而不是允许 OP 想要的“自定义值”。
  • 原始问题没有说明可以返回在 table2 中没有匹配记录的非空值。要设置默认值,如果值为空,您可以使用: SELECT table1.id, table1.description, ISNULL(table2.name, 'John'), ISNULL(table2.surname, 'Smith') FROM table1 LEFT JOIN table2 ON table1.EmpID = table2.EmpID;
【解决方案2】:

尝试使用 UNION:

SELECT table1.id, table1.description, table2.name, table2.surname 
FROM table1 
INNER JOIN table2 ON table1.EmpID = table2.EmpID
UNION
SELECT table1.id, table1.description, 'Table 2 Null', 'Table 2 Null'
FROM table1
WHERE table1.empId is null

【讨论】:

    【解决方案3】:

    如果表 1 为空,并且您仍然需要无法从该表开始的记录。从table2开始,加入table1。

    SELECT table1.id, table1.description, ISNULL(table1.empid, "some new value") AS name, table2.surname 
    FROM table2 
        LEFT OUTER JOIN table1 ON table2.EmpID = table1.EmpID
    

    【讨论】:

      【解决方案4】:
      SELECT table1.id
             ,table1.description
             ,COALESCE(table2.name, 'DEFAULT') AS name
             ,COALESCE(table2.surname, 'DEFAULT') AS surname
      FROM table1 
      LEFT JOIN table2
          ON table1.EmpID = table2.EmpID
      

      现在请注意,当 EmpID 不为 null 但如果他们在 table1 中有 EmpID 但在 table2 中没有找到它时仍然“无效”时,这也将包括人,所以如果这是你想要避免的事情,另一个选项是这样的:

      SELECT table1.id
             ,table1.description
             ,table2.name
             ,table2.surname
      FROM table1 
      INNER JOIN table2
          ON table1.EmpID = table2.EmpID
      
      UNION ALL
      
      SELECT table1.id
             ,table1.description
             ,'DEFAULT' AS name
             ,'DEFAULT' AS surname
      FROM table1 
      WHERE table1.EmpID IS NULL
      

      【讨论】:

        【解决方案5】:
        Select table1.id table1.description
            , Case When table1.EmpID Is Null Then 'Some Value' Else table2.name End As Table2Name
            , Case When table1.EmpID Is Null Then 'Some Value' Else table2.surname End As Table2Surname
        From table1
            Left Join table2
                On table2.EmpID = table1.EmpID
        Where table1.EmpID Is Null
                Or table2.EmpID Is Not Null
        

        【讨论】:

        • 这也将替换现有记录中的空值; table2.surname 可能合法地为空,并且 OP 仅表示他想要不存在记录的自定义值。此外,如果 table1.empID 不为 null,但没有具有该 empID 的 table2,则仅当 table1.empID 为 null 时,OP 才希望显示 table1 记录。
        • @KeithS - WRT 将姓氏或名字设为空,我们不会被告知它们是否可以为空。无论如何,我重新设计了我的解决方案来解决这个问题。
        猜你喜欢
        • 2011-03-28
        • 1970-01-01
        • 1970-01-01
        • 2012-01-28
        • 2017-01-01
        • 2014-07-10
        • 2015-02-03
        • 2010-11-23
        • 2013-11-17
        相关资源
        最近更新 更多