SQL服务器中的SQL百分比计算实例

5,922 阅读7分钟

在这篇文章中,你将看到计算多个列和行之间的SQL百分比的不同方法。你还将看到如何计算数字列的SQL百分比,并对分类列进行分组。你将使用子查询、OVER子句和通用表表达式(CTE)来寻找SQL百分比。

那么,让我们开始吧,不用多说了。

使用两个变量查找百分比

在SQL Server中没有内置的运算符来计算百分比。你必须依靠基本的算术运算,即(数字1/数字2 x 100)来寻找SQL Server中的百分比。

在查找跨行和跨列的SQL百分比之前,首先让我们看看如何使用SQL Server中的两个基本变量查找百分比。

下面的脚本定义了三个浮动变量@num1、@num2和@perc。接下来,@num2变量除以@num1变量,结果乘以100,存储在@perc变量中并打印在控制台中。

DECLARE @num1 as FLOAT
DECLARE @num2 as FLOAT
 
DECLARE @perc as FLOAT
SET @num1 = 150
SET @num2 = 50
 
SET @perc = @num2/@num1 * 100
 
PRINT @perc

输出。

result of basic percentage

寻找两列之间的百分比

查找两列之间的百分比是很简单的。你可以简单地使用列名和除法运算符"/",将一列中的数值除以另一列。其结果是一个数值的列表,对应于两列中所有数值的除法结果。

让我们看一个例子。

下面的脚本创建了一个带有两列浮点型 "获得 "和 "总计 "的表Result。该脚本还在Result表中插入了五条假行。然后,SELECT查询选择了结果表中的所有记录。下面是一个例子。

CREATE TABLE Result(obtained float, total float)
INSERT INTO Result values(15,50),(10,50),(20,50),(40,50),(25,50)
 
SELECT *
FROM Result

输出。

percentages accross columns

让我们试着找出每一行的百分比,作为 "获得 "和 "总计 "两列数值的除法结果,如下图所示,其中增加了一个新的百分比列。

SELECT obtained, total, obtained/total * 100 as 'percentage'
FROM Result

Result set

通过子查询查找百分比

寻找两列之间的SQL百分比是很直接的。然而,在不同的情况下,寻找跨行的百分比的过程就不那么简单了。

让我们先讨论一个非常简单的情况,即你必须找到一个列中的某个值在该列所有行中的百分比是多少。

下面的脚本创建了一个有一列的Scores表。

CREATE TABLE Scores(val float)
INSERT Scores(val) values(15),(10),(20),(40),(25);
 
SELECT *
FROM Scores

输出。

result of percentage via subquery

现在,如果你想知道每个数值占 "val "列中总数值的百分之几,你可以使用子查询。

在这方面,外层查询将把 "val "列中的所有数值乘以100,然后再除以子查询的结果,子查询找到 "val "列中所有数值的总和。

让我们先看看我们的子查询是如何计算 "val "列中的数值之和的。

SELECT SUM(val) as 'Total Sum'
FROM Scores

输出。

Output of SUM

下面的脚本返回 "val "列中每个值占总数的百分比。

SELECT val,
val * 100/(SELECT SUM(val) FROM Scores) as 'Percentage of Total'
From Scores

percentage of total values using subqueries

如果你不想在计算总数的百分比时排除任何数值,你可以用WHERE子句来做,如下面的脚本所示,其中不包括数值40。

SELECT val,
val * 100/(SELECT SUM(val) FROM Scores WHERE val < 40) as 'Percentage of Total' From Scores WHERE val < 40

percentage of total values using subqueries with WHERE clause

你可以从上面的输出中看到,由于删除了数值40,现在的数值占总数值的百分比更大。

最后,作为附带说明,你可以使用 "round "函数将返回的百分比四舍五入,如下所示。下面的脚本将百分比值四舍五入到小数点后2位。

SELECT val,
round(val * 100/(SELECT SUM(val) FROM Scores WHERE val < 40), 2) as 'Percentage of Total' From Scores WHERE val < 40

输出。

percentage of total values using subqueries with ROUND OFF

现在让我们看看如何计算SQL百分比的一个实际例子。

运行下面的脚本,看看产品表中的列。

USE Northwind
SELECT * FROM Products

输出。

Products table from Northwind database

产品表包含了一些列,这些列包含了Northwind数据库中的供应商ID,类别ID,单价和其他关于产品的信息。

考虑一个场景,你必须找到每个供应商提供的产品的百分比。为了找到这样的百分比值,你需要两个数值。

  1. 所有产品的总数,你可以通过COUNT函数得到这个数字。
  2. 每个供应商提供的产品总数,您可以通过GROUP BY函数获得。

然后您可以将第二个值(按供应商ID分组的产品数)乘以100,然后将结果除以第一个值(产品总计数)。

下面是你如何使用子查询来找到这种SQL百分比的方法。

USE Northwind
SELECT SupplierID, count(*) * 100.0 / (SELECT count(*) from Products) as 'Supplier Percentage'
FROM Products
GROUP BY SupplierID

输出。

percentage of total products by suppliers

上面的结果显示,每个供应商提供的产品的百分比。例如,你可以看到id为1的供应商提供的产品占总产品的3.89%。

使用Over条款

Over子句是一个非常有用的Window函数,可以在一个数值范围内计算数值。你也可以使用Over子句来计算SQL的百分比。使用Over子句,你可以避免使用子查询来计算百分比。

让我们看一个例子。下面的脚本找到每个供应商提供的产品的百分比。你可以看到,下面的脚本与你在上一节中看到的非常相似。但是,在这种情况下,我们没有使用子查询来返回所有产品的数量,而是使用了Over子句来返回所有产品的总数。

USE Northwind
SELECT SupplierID, count(*) * 100.0 / sum(count(*)) Over() as 'Supplier Percentage'
FROM Products
GROUP BY SupplierID

下面的输出与你使用子查询取得的结果相似。

输出。

result of calculating percentage using OVER clause

现在让我们看一个更复杂的查找SQL百分比的例子。考虑一种情况,对于每个供应商,你想计算所有产品的单价百分比。换句话说,你想找出所有产品的单价之和中有多少百分比是支付给不同的供应商的。你可以在OVER子句的帮助下做到这一点,如下所示。

在下面的脚本中,供应商ID与支付给所有供应商的单价之和,以及支付给所有供应商的单价百分比一起显示。

要计算单价之和,公式很简单,你可以使用SUM函数并将其传递给包含单价的列。

要计算单价的百分比,你需要将每个供应商的单价之和乘以100,然后将结果除以所有供应商的单价之和。在下面的脚本中,在分母部分,SUM函数被调用了两次。因为我们使用的是OVER运算符,所以第一个SUM函数只加了每个供应商的价格。为了找到支付给所有供应商的单价之和,我们调用了另一个SUM函数。

USE Northwind
 
SELECT SupplierID, SUM(UnitPrice) as 'Total Price Product',
(SUM(UnitPrice) * 100 )/SUM(SUM(UnitPrice)) OVER () as 'Percentage of Total Price'
 
FROM Products
GROUP BY SupplierID

在下面的输出中,你可以看到供应商ID,支付给每个供应商的单价之和以及每个供应商的单价百分比。

输出。

percentage of total prices in products table

使用普通表的表达式

最后,你也可以使用通用表表达式(CTE)来计算百分比。首先让我们看看如何使用CTE来查找两列数值之间的百分比。

下面的脚本通过用 "获得 "列中的值除以 "总计 "列中的值来找到百分比。

SELECTING results via CTE

WITH ResultCTE(Obtained, Total, Percentage)
AS
(
SELECT obtained,
total,
(obtained/total) * 100 Percentage
FROM Result
)
SELECT * FROM ResultCTE

finding simple percentages via CTE

你可以使用CTE表达式来寻找更复杂的SQL百分比,就像你使用OVER子句一样。例如,下面的脚本使用CTE来计算每个供应商所提供产品的百分比。

USE Northwind;
with ProductCTE(SupplierID, Supplier_Count)
as
(
select SupplierID, count(*)
from Products
group by SupplierID
)
SELECT SupplierID, Supplier_Count * 100.0/(select sum(Supplier_Count) from ProductCTE) as 'Percentage Supplies'
from ProductCTE;

其结果与你通过OVER子句实现的结果相似。

输出。

calculating percentages via CTE

最后,你还可以将OVER子句与CTE结合使用来计算百分比。例如,下面的脚本使用CTE查找每个供应商提供的产品的百分比,以及支付给所有供应商的所有产品的单价的百分比。

USE Northwind;
with ProductCTE(SupplierID, Supplier_Count, Price_Percentage)
as
(
select SupplierID, SUM(UnitPrice) as 'Total Price Product',
(SUM(UnitPrice) * 100 )/SUM(SUM(UnitPrice)) OVER () as 'Percentage of Total Price'
from Products
group by SupplierID
)
SELECT *
from ProductCTE;

calculating percentage of total product prices via the CTE

总结

在这篇文章中,我们研究了计算多列和多行之间SQL百分比的不同方法。