是否有一个 SQL 命令来计算不同列中值的频率?

Posted

技术标签:

【中文标题】是否有一个 SQL 命令来计算不同列中值的频率?【英文标题】:Is there an SQL command to count frequencies of a value in different columns? 【发布时间】:2020-10-22 10:51:27 【问题描述】:

我有一个非常庞大的教育项目捐赠数据集。我已经做了一些处理,对于这个问题,有三个感兴趣的表:项目、资金和类别。

项目包含项目 ID、其他一些可忽略的信息(例如开始日期)和项目所属的类别 ID。项目可以属于一个或两个类别,因此每个项目有两列。如果一个项目只属于一个类别,则类别 2 为 NULL。总共有 8 个类别,类别 ID 从 1 到 8。 Funding 包含项目 ID、其他一些可忽略的信息(例如总成本)和项目的当前状态。这要么是“全额资助”,要么是“过期”,因为所有项目都已完成。 类别仅包含 2 列,一列具有 8 个类别 ID,另一列具有类别名称(1 - 体育、2 - 科学等)。
*Project*
project_id  category_id1 category_id2
...             ...         ...
...             ...         ...

*Funding*
project_id  status
...          ...
...          ...

*Category*
Category_ID   project_category
...                   ...
...                   ...

我现在正试图找出每个类别的完全资助的百分比,即(完全资助)/(完全资助+过期)。但是,我似乎无法找到一种方法来为每个类别制作 SQL 计数实例,无论它们是在“项目”表的类别列 1 还是类别列 2 中。这是我到目前为止的输出代码:

SELECT project_category, status, count(project_category)
FROM Project
INNER JOIN Category ON Project.Category_ID1 = Category.Category_ID
INNER JOIN Funding ON Project.project_id = Funding.project_id
GROUP BY project_category, status 
project_category    status    count(project_category)
Applied Learning    Expired        4003
Applied Learning  Fully Funded     11441
Essentials          Expired           16
Essentials        Fully Funded       219
Health & Sports     Expired         1235
Health & Sports   Fully Funded      4518
...                 ....             ...
...                 ....             ...

此输出仅计算 project.category_id1 中的类别。我可以为 project.category_id2 创建另一个表并手动添加它们,但我宁愿有一个表。有没有办法做到这一点? 感谢您的帮助!

【问题讨论】:

资助状态不在项目表中,而是在单独的资助表中。这是否意味着一个项目可以有多个状态?或者为什么这是一个单独的表? 【参考方案1】:

您可以取消透视然后聚合:

SELECT c.project_category, f.status, count(*)
FROM (SELECT p.project_id1 as project_id, p.Category_ID FROM Project p
      UNION ALL
      SELECT p.project_id2 as project_id, p.Category_ID FROM Project p
     ) p JOIN
     Category c
     ON p.Category_ID = c.Category_ID JOIN
     Funding f
     ON p.project_id = f.project_id
GROUP BY c.project_category, f.status;

请注意,这也引入了表别名和限定的所有列引用。

Here 是一个 dbfiddle。

【讨论】:

感谢您的回复,我没有使用表别名的经验,但我想这没问题。但是,当我运行代码时,我得到一个语法错误'near Union'。你知道这是为什么吗? @KevinLucas 。 . .我修正了一些拼写错误(但我认为它们不会导致该错误)并添加了一个 dbfiddle 说明查询在语法上是正确的。 @KevinLucas 。 . . SQLite 出于某些奇怪和神秘的原因,不允许在 FROM 子句中使用 UNION ALL 围绕子查询使用括号。我想这是宇宙的奥秘之一。

以上是关于是否有一个 SQL 命令来计算不同列中值的频率?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取列中值的不同百分比并将它们相加以分配到新的 SQL 列中?

周期噪声频域滤除散粒噪声中值滤波

python 获取列中值的频率

如何在 Python 中提取以下频域特征?

获取列中值的计数并在图中显示它们的百分比

如何使用Qt计算表中值的频率