【问题标题】:TSQL: how to eliminate join on Null values when Column value is availableTSQL:当列值可用时如何消除空值连接
【发布时间】:2015-12-29 06:15:25
【问题描述】:

我有一个场景,我必须加入以下两个表

Create Table tbl1(col1 int, col2 int, col3 int)
Create Table tbl2(col1 int, col2 Varchar)

样本数据:

 Insert tbl1 Values(1, 1, 1), (2, 2, 1), (3, 3, 2), (4, 4, 3)
 Insert tbl2 Values(1, 'A'), (2, 'B'), (NULL, 'C'), (4, 'D')

我使用了以下查询:

select * 
from tbl1 
Left join tbl2 on tbl1.Col3 = @value 
               and tbl1.col2 = tbl2.col1

后来情况发生了变化,我们必须在 tbl1.col1 为空时获取这些值,所以我使用了这个查询:

select * 
from tbl1 
Left join tbl2 on tbl1.Col3 = @value 
               and (tbl1.col2 = tbl2.col1 or tbl2.col1 is null)

它也可以正常工作,但问题在于 tbl1.col1 具有匹配值以及 tbl2.col1 中为 null 的一些数据。在这种情况下,我们会得到多条记录,这些记录是错误的数据。

例如不正确的o/p是这样的:

1   1   1       A
1   1   NULL    C
2   2   2       B
2   2   NULL    C
3   3   NULL    C
4   4   NULL    C
4   4   4       D

但是我们想要这样的 O/P

1   1   1       A
2   2   2       B
3   3   NULL    C
4   4   4       D

我的要求是从 tbl1.col2 = tbl2.col1 或从 tbl2.col1 获取空值(tbl2.col1 为空)但是当 tbl2.col1 不为空时,或条件(tbl2.col1 为null) 不应该被执行。

请给我一些建议。

【问题讨论】:

  • 请正确格式化您的问题并提供示例数据。
  • 你怎么知道(NULL, 'C')只能和(3,3,2)记录一起加入?如果我添加(NULL, 'E'),结果会怎样,在当前查询中,它将与 tbl1 中的所有行连接。此外,如果您执行select *,您应该会在结果中获得 5 列。
  • 如果在 tbl1 中有第 5 行,输出会是什么?第 5 行的输出也会为 'NULL' 吗?
  • @EdwinStoteler,实际上我在复制 o/p 时犯了错误,错过了 tbl1.col3。感谢您注意到这一点。 “@value”也作为参数传递到我的 SP 中。我的 o/p 完全依赖于 tbl1.col1、tbl1.col2 和 tbl2.col1
  • 是的@Mark,o/p 应该是第 5 行也是 'NULL' 但如果 tbl1 的第 5 行有任何匹配记录,则 o/p 中的 'NULL' 应该被消除。跨度>

标签: sql-server


【解决方案1】:

首先我们得到所有匹配的值

SELECT * 
FROM tbl1 
INNER JOIN tbl2 ON tbl1.col2 = tbl2.col1
WHERE tbl1.Col3 = @value 

然后我们联合所有

UNION ALL

包含所有尚未加入的值

SELECT * 
FROM tbl1 
LEFT JOIN tbl2 ON tbl2.col1 IS NULL
WHERE tbl1.Col3 = @value 
   AND NOT EXISTS (
      SELECT * 
      FROM tbl2 tbl2_2
      WHERE tbl1.col2 = tbl2_2.col1)

由于这是一个存储过程,您可以通过使用临时表来存储第一部分的结果来提高性能。

【讨论】:

  • 谢谢@Edwin Stoteler :)
猜你喜欢
  • 2018-09-08
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多