我目前正在攻读我的MCSA数据平台,我得到了以下错误的问题,我正在寻找一个解释,为什么我的答案是错误的,因为测试解释没有多大意义。
Hovercraft Wages表记录了Contoso工人的工资。工人可以获得每日工资或年薪。该表包含以下列:
EmpID,Daily_Rate,Yearly_Salary
工人只获得一种收入率,而其记录中的另一列的值为NULL。您希望运行一个查询来计算每个员工的总薪水,假设人们每周工作5天,每年52周。
下面是两个选项,正确答案和我选择的答案
SELECT EmpID, CAST(COALESCE(Daily_Rate*5*52, Yearly_Salary) AS money) AS 'Total Salary'
FROM Hovercraft.Wages;
SELECT EMPID, CAST(ISNULL(Daily_Rate*5*52, Yearly_Salary)AS money)AS 'Total Salary'
FROM Hovercraft.Wages;
我选择了第二个选项,因为只有两个可能的付费字段,但被标记为合并不正确,任何人都可以澄清为什么ISNULL在这个例子中不是一个有效的选择,因为我不想在这个例子中犯这个错误将来
非常感谢
答案 0 :(得分:3)
最大的区别是ISNULL
是专有的,而COALESCE
是SQL标准的一部分。认证课程可以教授最大程度的知识可移植性,因此当您有多种选择时,课程更喜欢解决问题的标准方法。
在这种情况下可能重要的另一个差异是数据类型确定。 ISNULL
使用第一个参数的类型,而COALESCE
遵循与CASE
相同的规则,并选择具有更高优先级的类型。当Daily_Rate
存储在范围较窄的列中时,这可能很重要。
为了完整性,这里列出了两者之间的其他差异(taken from Microsoft SQL Server Blog):
ISNULL
和COALESCE
的验证不同,因为NULL
的{{1}}值已转换为ISNULL
,但int
会触发错误} COALESCE
仅使用两个参数,而ISNULL
采用可变数量的参数 编辑:从答案措辞的方式来看,我认为作者希望您在第二个参数保证为非NULL的情况下使用COALESCE
,例如:不可空的字段或常量。虽然通常这个想法是合理的,但是他们选择测试它的问题并不理想:问题是问题保证第二个ISNULL
参数的值在重要的情况下是非NULL的,这使得两个选择在逻辑上等同。
答案 1 :(得分:0)
除了所有众所周知的差异之外,没有多少人知道COALESCE
只是CASE
的简写,并且继承了所有这些&#s; s和-s - 列表参数,适当的结果铸造等。
但对于一个毫无戒心的开发者来说,这也可能是性能的下降。
为了证明我的观点,请运行这三个查询(在AdventureWorks2012数据库上)并检查它们的执行计划:
SELECT COALESCE((SELECT CustomerID FROM Sales.SalesOrderHeader WHERE SalesOrderId = 57418), 0)
SELECT ISNULL((SELECT CustomerID FROM Sales.SalesOrderHeader WHERE SalesOrderId = 57418), 0)
SELECT CASE WHEN (SELECT CustomerID FROM Sales.SalesOrderHeader WHERE SalesOrderId = 57418) IS NULL
THEN 0
ELSE (SELECT CustomerID FROM Sales.SalesOrderHeader WHERE SalesOrderId = 57418)
END
您会看到第一个和第三个具有相同的执行计划(因为COALESCE只是CASE的简短形式)。另外,您会看到在第一个和第三个查询中,SalesOrderHeader表被访问两次,因为ISNULL只使用了一次。
如果您还为会话启用了SET STATISTICS IO ON
,那么您会注意到这两个查询的逻辑读取次数是两倍。
在这种情况下,COALESCE
执行了两次内部SELECT语句,而ISNULL
只执行了一次。这可能会产生巨大的差异。