通过不相关的查询划分相关查询

时间:2015-08-28 18:48:53

标签: sql sql-server sql-server-2012

我正在尝试编写一个SELECT语句,它将根据两个查询的结果计算百分比。

我需要划分生成VulnerabilityCount和VulnerabilityCountAll的两个子查询的结果。我也将结果四舍五入到小数点后两位。

以下是代码:

 SELECT tblControl.ControlName,
     (SELECT COUNT(CONVERT(REAL,tblVulnerability.VulnerabilityID))
     FROM tblVulnerability
     WHERE tbl.Vulnerability.ControlID = tblControl.ControlID ) AS VulnerabilityCount,

     (SELECT COUNT(CONVERT(REAL,tblVulnerability.VulnerabilityID))
     FROM tblVulnerability) AS VulnerabilityCountAll, 

     /* This is where I am dividing the two subqueries */
     (SELECT(ROUND(CONVERT(REAL,(
          (SELECT COUNT(CONVERT(REAL,tblVulnerability.VulnerabilityID))
      FROM tblVulnerability
      WHERE tbl.Vulnerability.ControlID = tblControl.ControlID )
      /
     (SELECT COUNT(CONVERT(REAL,tblVulnerability.VulnerabilityID))
     FROM tblVulnerability)
     )),2))) AS Percentage

 FROM tblControl
 WHERE tblControl.Effectiveness = '10'
 ORDER BY VulnerabilityCount DESC, tblControl.ControlName ASC

查询将运行,但它为Percentage列生成值“0”而不是真实的百分比。

2 个答案:

答案 0 :(得分:0)

计数函数的输出是整数。您将整数除以整数,因此操作的输出类型是整数。您应该在计数值而不是参数上转换为实数...就像这样:

 SELECT tblControl.ControlName,

     (SELECT CONVERT(REAL,COUNT(tblVulnerability.VulnerabilityID))
     FROM tblVulnerability
     WHERE tbl.Vulnerability.ControlID = tblControl.ControlID ) AS VulnerabilityCount,

     (SELECT CONVERT(REAL,COUNT(tblVulnerability.VulnerabilityID))
     FROM tblVulnerability) AS VulnerabilityCountAll, 

     /* This is where I am dividing the two subqueries */
     (SELECT(ROUND(CONVERT(REAL,(
          (SELECT CONVERT(REAL,COUNT(tblVulnerability.VulnerabilityID))
      FROM tblVulnerability
      WHERE tbl.Vulnerability.ControlID = tblControl.ControlID )
      /
     (SELECT CONVERT(REAL,COUNT(tblVulnerability.VulnerabilityID))
     FROM tblVulnerability)
     )),2))) AS Percentage
 FROM tblControl
 WHERE tblControl.Effectiveness = '10'
 ORDER BY VulnerabilityCount DESC, tblControl.ControlName ASC

虽然可能更有效和更清晰的查询将使用与组的连接:

 select tblControl.ControlName,
    COUNT(tblVulnerability.VulnerabilityID) VulnerabilityCount,
    (select COUNT(VulnerabilityID) from tblVulnerability) as VulnerabilityCountAll,
    CONVERT(REAL,COUNT(tblVulnerability.VulnerabilityID))
        / (select COUNT(VulnerabilityID) from tblVulnerability) AS Percentage
 from tblControl
 join tblVulnerability
 on tblControl.ControlID = tblVulnerability.ControlID
 where tblControl.Effectiveness = '10'
 Group by tblControl.ControlName 
 ORDER BY VulnerabilityCount DESC, tblControl.ControlName ASC

答案 1 :(得分:0)

我在你的问题中发现很多遗失的部分。样本数据和您期望的内容将有助于提供准确的答案。我试着回答你在查询中的逻辑。 如果你的意思是你运行了上面提供的查询,我相信它会抛出错误,因为你有 tbl.Vulnerability .ControlID = tblControl.ControlID 我相信表名是tblVulnerability。

为了数数,为什么你需要将ID转换为Real类型?我不确定逻辑或需要是否为Sum,我根据您的问题中所述的计数提供答案。希望这会有所帮助。

 with VC
 (
 select tblVulnerability.ControlID , 
 count(*) over (Partition by ControlID) as ControlVulnerabilityCount
 , count(*) as VulnerabilityCount
 from tblVulnerability
 )
 select tblControl.ControlName,VC.CntV  AS VulnerabilityCount,
 (VC.ControlVulnerabilityCount/ VC.VulnerabilityCount) as Percentage
 from tblControl tc
 join VC on VC.ControlID = tc.ControlID
  WHERE tblControl.Effectiveness = '10'
  order by VC.ControlVulnerabilityCount desc, tblControl.ControlName ASC