如何将两个独立SQL子查询结果相除得到Total_X列?
解决方案:计算两个统计结果的比率
嘿,我懂你现在的需求啦——就是要把这两个查询的结果(分子114、分母131)做除法,得到名为Total_X的最终比率对吧?其实不用纠结union、cross join这些复杂的语法,有几个简单高效的方法可以实现,我给你详细说下:
方法一:直接用子查询做除法
这个方法最直观,把两个查询分别作为子查询,直接在主查询里完成除法运算。注意要把其中一个值转成浮点型,避免整数除法导致结果被截断:
SELECT CAST( (SELECT COUNT(*) FROM ( SELECT *, DATEDIFF(SECOND, xx, yy) AS SecondDiff, DATEDIFF(DAY, xx, yy) AS DayDiff FROM database1.dbo.tbl1 WHERE MONTH(datecompleted) = MONTH(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) AND YEAR(datecompleted) = YEAR(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) AND DATEDIFF(DAY, xx, yy) <= 15 ) t1) AS FLOAT ) / (SELECT COUNT(*) FROM ( SELECT *, DATEDIFF(SECOND, xx, yy) AS SecondDiff, DATEDIFF(DAY, xx, yy) AS DayDiff FROM database1.dbo.tbl1 WHERE MONTH(datecompleted) = MONTH(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) AND YEAR(datecompleted) = YEAR(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) ) t2) AS Total_X
方法二:用CTE优化(推荐)
上面的方法会重复扫描两次表,效率稍低。用CTE(公共表表达式)可以只扫描一次表,同时计算出分子和分母,代码也更简洁:
WITH FilteredData AS ( -- 先筛选出上个月的数据,只保留需要的DayDiff字段 SELECT DATEDIFF(DAY, xx, yy) AS DayDiff FROM database1.dbo.tbl1 WHERE MONTH(datecompleted) = MONTH(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) AND YEAR(datecompleted) = YEAR(DATEADD(MONTH, -1, CURRENT_TIMESTAMP)) ), Stats AS ( -- 一次计算出分母(总记录数)和分子(符合DayDiff<=15的记录数) SELECT COUNT(*) AS Denominator, SUM(CASE WHEN DayDiff <= 15 THEN 1 ELSE 0 END) AS Numerator FROM FilteredData ) -- 最后做除法得到比率 SELECT Numerator, Denominator, CAST(Numerator AS FLOAT) / Denominator AS Total_X FROM Stats
为什么你之前的方法没成功?
union是用来合并多个结构相同的结果集,不是用来做数值运算的,所以肯定达不到你的需求;cross join如果没处理好会产生笛卡尔积,除非你把两个查询都转成单值的子表,不过这种写法不如上面的方法直观;cross apply更多用于关联子查询,这里其实不需要关联逻辑,所以用它反而绕远路啦。
你现在在补SQL基础,这个问题很典型,核心就是学会把聚合结果提取出来做运算,上面的第二种方法效率更高,推荐你优先使用哦~
内容的提问来源于stack exchange,提问作者Pat
相关产品推荐
相关产品推荐

