如何在SQL查询中校验标量函数结果与x4.code列值不相等
实现标量函数结果与列值不相等的条件校验
没问题,你可以通过两种实用的方式来给你的SQL查询添加这个校验条件,下面分别说明:
方法1:直接在WHERE子句中添加条件
这种方式最简单直接,直接把标量函数的调用和x4.code的比较逻辑加到WHERE子句里即可。不过要注意,如果函数返回NULL或者x4.code为NULL,<> 运算符会返回UNKNOWN,这部分数据会被过滤掉;如果你的业务需要包含NULL的情况,可以额外补充判断:
select x1.name, x1.owner, (Select dbo.GetTopEmployerName(x1.unit)), X2.searchName, x4.code,x6.status From dbo.profile X1 Join dbo.profilevalues x3 on X1.profileId == x3.profileKey Left outer join dbo.profilecontact X2 on x1.unit = X2.ctId Join dbo.accessright x4 on x3.accessrightsId == x4.accessrightId Left outer join dbo.profilecontact x5 on x1.owner = x5.contactId Left outer join dbo.status x6 on x1.statusId = x6.statusId Where ((X4.accessRightid in (200,300,400))) -- 添加的校验条件 AND dbo.GetTopEmployerName(x1.unit) <> x4.code;
如果需要处理NULL场景(比如函数结果为NULL或者x4.code为NULL时也保留这些行),可以修改条件为:
AND (dbo.GetTopEmployerName(x1.unit) <> x4.code OR dbo.GetTopEmployerName(x1.unit) IS NULL OR x4.code IS NULL);
方法2:使用CTE/子查询避免重复调用函数
第一种方法里,标量函数会在SELECT和WHERE中各调用一次,当数据量较大时可能影响性能。你可以用CTE(公共表表达式)先计算出函数的结果,再在外部查询中进行过滤,这样函数只需要调用一次:
WITH ProfileCTE AS ( select x1.name, x1.owner, dbo.GetTopEmployerName(x1.unit) as TopEmployerName, X2.searchName, x4.code, x6.status From dbo.profile X1 Join dbo.profilevalues x3 on X1.profileId == x3.profileKey Left outer join dbo.profilecontact X2 on x1.unit = X2.ctId Join dbo.accessright x4 on x3.accessrightsId == x4.accessrightId Left outer join dbo.profilecontact x5 on x1.owner = x5.contactId Left outer join dbo.status x6 on x1.statusId = x6.statusId Where X4.accessRightid in (200,300,400) ) SELECT name, owner, TopEmployerName, searchName, code, status FROM ProfileCTE WHERE TopEmployerName <> code;
同样,如果需要处理NULL场景,把WHERE条件改成:
WHERE TopEmployerName <> code OR TopEmployerName IS NULL OR code IS NULL;
小提示
标量函数在SQL Server中性能往往不如表值函数或者直接的查询逻辑,如果这个函数的逻辑可以用JOIN或者其他方式替换,长远来看更推荐重构函数逻辑,避免因为大量调用标量函数导致查询变慢。
内容的提问来源于stack exchange,提问作者Prajakta Koli




