2017-09-06 115 views
2

我有这样的数据:SQL Server添加在空where子句

+-----+-------+-------+-------+-------+ 
| id | val1 | val2 | val3 | val4 | 
+-----+-------+-------+-------+-------+ 
| 1 |  5 | null |  0 |  3 | 
+-----+-------+-------+-------+-------+ 

我想选择所有行val1-4的增加数超过一定阈值。但是列可以为空。所以这是行不通的:

SELECT * 
FROM data 
WHERE val1 + val2 + val3 + val4 > 6 

我可以使用:

SELECT * 
FROM data 
WHERE ISNULL(val1, 0) + ISNULL(val2, 0) + ISNULL(val3, 0) + ISNULL(val4, 0) > 6 

不过,我看到,在一个WHERE条款使用ISNULL当SQL Server无法使用索引。

这是真的吗?我还有什么其他选择?

+0

问题是什么?你使用了'ISNULL'并且需要很长时间?此外,所有这些列索引? – sagi

+0

无论如何SQL Server将无法使用索引搜索,因为您正在对列执行添加。这是一个完整的扫描,如果所有值都被编入索引,可能是索引,但它不是索引查找。 – dasblinkenlight

+0

在我这边是坏思想过程..当然,指数无论如何也无济于事。所以我想ISNULL或者COALESCE不会损害整体性能,而不是使用它。 – Chris

回答

2

我会用coalesce()

SELECT * 
FROM data 
WHERE COALESCE(val1, 0) + COALESCE(val2, 0) + COALESCE(val3, 0) + COALESCE(val4, 0) > 6 

当然,SQL Server无法使用索引来进行,是因为功能。实际上,它也不能与+一起使用索引,所以你没有失去任何东西。

如果你想使用一个索引,然后再加上该指数计算列和列:

alter table data add total_value as 
    (COALESCE(val1, 0) + COALESCE(val2, 0) + COALESCE(val3, 0) + COALESCE(val4, 0)) persisted; 

create index idx_data_total_value on data(total_value); 

然后短语查询为:

where total_value > 6 
+0

你使用COALESCE而不是ISNULL的原因是什么? – Cosmin

+0

@Cosmin。 。 。这是ANSI标准功能。我意识到'ISNUL()'在某些情况下更有效率,但这不是其中之一。 –

+0

@Cosmin我想你会发现'COALESCE'是更标准的解决方案 - 它是ANSI标准。 – Manngo