处理NULL和空字符串值时编写联合查询的最佳方法

时间:2010-08-19 19:17:57

标签: sql sql-server tsql

我必须编写一个查询,在具有相似数据的两个表之间执行联合。结果需要明确。我遇到的问题是,当涉及到空值时,某些字段应该是相同的。一些被指示为null,一些具有空字符串值。我的问题是,有没有更好的方法来执行以下查询? (没有修复实际数据以确保设置正确的默认值等)将使用案例什么时候会有很大的性能影响?

Select  
    When Column1 = '' Then NULL Else Column1 as [Column1],
    When Column2 = '' Then NULL Else Column2 as [Column2]
From TableA

UNION ALL

Select 
    When Column1 = '' Then NULL Else Column1 as [Column1],
    When Column2 = '' Then NULL Else Column2 as [Column2]
From TableB

4 个答案:

答案 0 :(得分:3)

我认为它不会对性能产生任何影响,但是NULLIF是写这个的另一种方式,恕我直言,看起来更清洁。

Select  
    NULLIF(Column1, '') as [Column1],
    NULLIF(Column2, '') as [Column2]
From TableA

UNION

Select 
    NULLIF(Column1, '') as [Column1],
    NULLIF(Column2, '') as [Column2]
From TableB

答案 1 :(得分:1)

Case应该可以正常运行,但IsNull在这种情况下更自然。如果您正在搜索不同的行,那么执行union而不是union all将会实现这一点(感谢Jeffrey L Whitledge指出这一点):

select  IsNull(col1, '')
,       IsNull(col2, '')
from    TableA
union
select  IsNull(col1, '')
,       IsNull(col2, '')
from    TableB

答案 2 :(得分:1)

使用UNION删除重复项 - 此功能的速度低于UNION ALL

SELECT CASE 
         WHEN LEN(LTRIM(RTRIM(column1))) = 0 THEN NULL
         ELSE column1
       END AS column1,
       CASE 
         WHEN LEN(LTRIM(RTRIM(column2))) = 0 THEN NULL
         ELSE column2
       END AS column2
  FROM TableA
UNION 
SELECT CASE 
         WHEN LEN(LTRIM(RTRIM(column1))) = 0 THEN NULL
         ELSE column1
       END,
       CASE 
         WHEN LEN(LTRIM(RTRIM(column2))) = 0 THEN NULL
         ELSE column2
       END 
  FROM TableB

如果列值包含任意数量的空格且没有实际内容,我将逻辑更改为返回NULL。

CASE表达式是ANSI,比NULLIF / etc语法更可自定义。

答案 3 :(得分:0)

如果您在单独的视图中执行任何操作(将NULL替换为空字符串),则可以将操作操作与union分开,然后将视图合并。

但是,您不必在两个集合上应用相同的操作。

如果是这种情况,请先将它们联合起来,然后将操作应用于生成的联合集合。

支持这种方式的操作代码的一半。