我有这个返回Null的查询,显示0我可以在CAST周围的外部查询上使用ISNULL,我不知道在内部查询中使用ISNULL是否更好。
我尝试过使用带有内部查询的ISNULL,但它没有返回任何行而不是显示0.我尝试删除group by子句,但结果仍然相同。
SELECT CAST((SUM(q.AssingWithPO * 1.0) / SUM(q.TotalAssign * 1.0)) * 100
AS NUMERIC (10,2))
FROM
(
SELECT COUNT(DISTINCT a.AssignmentID) AS TotalAssign
,(SELECT COUNT(DISTINCT a2.AssignmentID)FROM Assignments a2
WHERE a2.PODeliveryDate <> '19001212'
AND a2.AssignmentID = a.AssignmentID ) AS AssingWithPO
FROM Assignments a
WHERE a.StaffID = 59
AND (a.CreatedDate BETWEEN '20130101' AND '20141231')
GROUP BY a.AssignmentID
)q;
ADDED
由于@Gordon
,我简化了这个查询SELECT SUM(case when a.PODeliveryDate <> '19001212' then 1.0 else 0.0 end) / COUNT(*)) * 100 as AssignWithPO
FROM Assignments a
WHERE a.StaffID = 59 AND
a.CreatedDate BETWEEN '20130101' AND '20141231';
现在可以像这样使用ISNULL吗?
ISNULL((SUM(a.PODeliveryDate&lt;&gt;'19001212'然后1.0,否则0.0结束)/ COUNT(*))* 100作为AssignWithPO,0)
两个查询的执行计划
答案 0 :(得分:1)
您不需要第二级子查询。您可以改为使用条件聚合。我认为以下内容可以满足您的需求:
SELECT CAST((SUM(a.AssignWithPO * 1.0) / SUM(a.TotalAssign * 1.0)) * 100 as NUMERIC (10,2))
FROM (SELECT COUNT(*) AS TotalAssign,
SUM(case when a.PODeliveryDate <> '19001212' then 1 else 0 end) as AssignWithPO
FROM Assignments a
WHERE a.StaffID = 59 AND
a.CreatedDate BETWEEN '20130101' AND '20141231'
GROUP BY a.AssignmentID
) a;
我不是百分百肯定,因为我不理解AssignmentId
,StaffId
和CreatedDate
之间的关系,但我的假设是行AssignWithPO
计算的条件与TotalCount
相同。
您不需要count(distinct)
,因为AssignmentId
因group by
而必然是唯一的。假设值之间没有重叠,您也不需要group by
,也不需要外部查询:
SELECT COUNT(*) AS TotalAssign,
SUM(case when a.PODeliveryDate <> '19001212' then 1.0 else 0.0 end) / COUNT(*) as AssignWithPO
FROM Assignments a
WHERE a.StaffID = 59 AND
a.CreatedDate BETWEEN '20130101' AND '20141231';