SQL select语句汇总几种情况并返回百分比?

Posted

技术标签:

【中文标题】SQL select语句汇总几种情况并返回百分比?【英文标题】:SQL select statement to sum totals of several cases and return percentage? 【发布时间】:2019-02-28 01:03:38 【问题描述】:

我有一个员工评估记录表,该表与另一个包含评估主题的表相关,它有 3 种评估类型,例如:

    负数和正数(分别在表“-3、-2”中表示为整数值)。 No & Yes(分别在表“-1, 0”中表示为整数值)。 从 1 到 5 的值(表示为具有相同值的整数)。

所以这是表格设计的一个例子:

--------------------
| evaID      | int |
--------------------
| employeeID | int |
--------------------
| evaRec     | int |
--------------------

这是表格数据的示例:

-------------------------------
| evaID | employeeID | evaRec |
-------------------------------
| 1     | 00001      | -3     |
-------------------------------
| 17    | 00001      | -2     |
-------------------------------
| 19    | 00001      | -2     |
-------------------------------
| 19    | 00001      | -1     |
-------------------------------
| 16    | 00002      | 3      |
-------------------------------
| 16    | 00005      | 0      |
-------------------------------

现在我想要的是根据类型选择特定员工的所有记录的总和作为评估的百分比,但将 3 种类型分开,例如前 (与该表数据无关) em>:

阴性和阳性类型:20% / 80% 否和是类型:30% / 70% 1、2、3、4或5型:10% / 50% / 5% / 15% / 20%

所以基本上我希望 select 语句返回 6 个浮点值,表示前面提到的所有类型的百分比(floatNegative、floatNo、float1、float2、float3 和 float4),如果可能的话 - 但我知道这很难,因为我还无法弄清楚它背后的逻辑 - 我希望它返回第 7 个浮点值,代表所有评价的百分比,比如差评和好评,但我还不知道如何混合“是或否”是 2 个因素百分比,“1,2,3,4 或 5”是 5 个因素百分比!

所以稍后在我的 c# 代码中,我将使用如下选择结果:

floatNegative = 20(负数 = 20%,正数 = 100-floatNegative = 80%) floatNo = 30(No = 30% 和 Yes= 100-floatNo = 70%) 以此类推,还有 5 个其他数字...

这意味着根据上述评估类型,我有 3 组独立的百分比计算。

所以最后,如果我从上表中对员工“00001”运行查询,我会得到结果:

floatNegative = 33.3 floatPositive = 66.6 floatNo = 100.0

因为他有 1 x “负面”记录 (-3) 和 2 x “正面”记录 (-2),总共 3 条记录。 (在“负面/正面”类型的评估组中),并且他有 1 x “否”记录(-1),但没有任何 ”是”记录 (0),这就是“否”的结果为 100% 的原因(在“否/是”类型的评估组中)。如果他没有任何记录(如 1、2、3、4、5),我不关心其他类型的结果,它可能是负浮点值,所以我可以在我的 c# 代码中区分它以找出他还没有关于这种类型的记录,并在我的 asp.net 最终标记中隐藏了百分比指示符文本。

【问题讨论】:

想要的结果真的很有帮助。 @GordonLinoff 编辑了问题,请再次阅读并感谢。 【参考方案1】:

我认为您正在寻找条件聚合。逻辑是GROUP BY employeeID,然后用各种SUM(CASE ...) epressions计算中间和。

假设你要统计一个员工的负面评价,那么你:

SUM(CASE WHEN evaRec = -2 THEN 1 ELSE 0 END)

您还计算正面和负面反馈的总数:

SUM(CASE WHEN evaRec IN (-2, -3) THEN 1 ELSE 0 END)

这是使用该原则的完整查询。对于二进制评估类型(正/负,是/否),仅计算两个值中的一个(另一个只是 1 - <this_value>)。对于 1/2/3/4/5 类型,每个比例都是单独计算的。

SELECT
    employeeID,
    1.0 * SUM(CASE WHEN evaRec = -2 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (-2, -3) THEN 1 ELSE 0 END), 0) PercentPositive,
    1.0 * SUM(CASE WHEN evaRec =  0 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (-1, 0)  THEN 1 ELSE 0 END), 0) PercentYes,
    1.0 * SUM(CASE WHEN evaRec =  1 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (1, 2, 3, 4, 5)  THEN 1 ELSE 0 END), 0) PercentValue1,
    1.0 * SUM(CASE WHEN evaRec =  2 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (1, 2, 3, 4, 5)  THEN 1 ELSE 0 END), 0) PercentValue2,
    1.0 * SUM(CASE WHEN evaRec =  3 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (1, 2, 3, 4, 5)  THEN 1 ELSE 0 END), 0) PercentValue3,
    1.0 * SUM(CASE WHEN evaRec =  4 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (1, 2, 3, 4, 5)  THEN 1 ELSE 0 END), 0) PercentValue4,
    1.0 * SUM(CASE WHEN evaRec =  5 THEN 1 ELSE 0 END) / NULLIF(SUM(CASE WHEN evaRec IN (1, 2, 3, 4, 5)  THEN 1 ELSE 0 END), 0) PercentValue5
FROM t
GROUP BY employeeID

注意:需要特别注意避免除以 0。

这个 DB Fiddle 与您的示例数据返回:

员工ID |正百分比 |百分比是 |百分比值1 |百分比值2 |百分比值3 |百分比值4 |百分比值5 ---------: | :---------------- | :------------- | :------------- | :------------- | :------------- | :------------- | :------------- 1 | 0.666666666666 | 0.000000000000 | | | | | 2 | | | 0.000000000000 | 0.000000000000 | 1.000000000000 | 0.000000000000 | 0.000000000000 5 | | 1.000000000000 | | | | |

【讨论】:

首先感谢您的简洁回答和您的时间/精力。我会将其标记为答案,尽管它并没有完全退出我想要的,但我可以调整它以按照我在问题中想要的方式获得结果(我不想要 DataTable 样式的结果,我只想要直接浮点输出但是在您解决了较难的部分后,这很容易调整),但它是完整、正确且非常聪明的方法。再次感谢!

以上是关于SQL select语句汇总几种情况并返回百分比?的主要内容,如果未能解决你的问题,请参考以下文章

数据库SQL语句学习笔记-汇总数据

PL/SQL:, 如何将变量传递给 SELECT 语句并返回所有结果行

SQL Server中怎样可以从SELECT语句的结果集中删除重复行

常用ClickHouse性能监控SQL汇总

sql语句中通配符有几种

sql查询语句并不是最先执行SELECT