You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算30天内各语言占比时遇MySQL报错,寻求解决方案

计算MySQL表中30天内各语言的占比问题

我有一个MySQL表,想要计算2020年11月1日至11月30日(30天)内,每种语言的占比。

我先写了这段SQL:

select language as languages, round(100*count(*)/total, 2)
from job_data
cross join (select count(*) as total from job_data) sub
group by language;

这段SQL运行报错(错误信息在输出标签页高亮显示)。

之后我又尝试了另一段SQL:

WITH CTE AS (
    SELECT Language, COUNT(job_id) AS num_jobs
    FROM job_data
    WHERE event IN("transfer","decision")
    AND ds >= "2020-11-01" AND  ds <= "2020-11-30"
    GROUP BY language),
total AS (
    SELECT COUNT(job_id) AS total_jobs
    FROM job_data
    WHERE event IN("transfer","decision")
    AND ds >= "2020-11-01" AND  ds <= "2020-11-30"
    GROUP BY language)
SELECT language, ROUND(100.0*num_jobs/total_jobs, 2) AS perc_jobs
FROM CTE
ORDER BY perc_job DESC;

出现错误:

Error Code: 1054. Unknown column 'total_jobs' in 'field list'

我知道第二段SQL的问题所在,但还是需要解决计算30天内各语言占比的需求。


解决方案

方法一:窗口函数(MySQL 8.0+适用)

窗口函数可以直接计算分组后的总数量,写法简洁高效:

SELECT 
    language,
    ROUND(100.0 * COUNT(job_id) / SUM(COUNT(job_id)) OVER (), 2) AS perc_jobs
FROM job_data
WHERE event IN("transfer","decision")
  AND ds BETWEEN "2020-11-01" AND "2020-11-30"
GROUP BY language
ORDER BY perc_jobs DESC;

SUM(COUNT(job_id)) OVER ()会直接计算出30天内符合条件的总职位数,作为占比计算的分母。

方法二:子查询关联(兼容低版本MySQL)

如果你的MySQL版本不支持窗口函数,可以用子查询先算出总数量,再关联计算:

SELECT 
    j.language,
    ROUND(100.0 * COUNT(j.job_id) / t.total_jobs, 2) AS perc_jobs
FROM job_data j
CROSS JOIN (
    SELECT COUNT(job_id) AS total_jobs
    FROM job_data
    WHERE event IN("transfer","decision")
      AND ds BETWEEN "2020-11-01" AND "2020-11-30"
) t
WHERE j.event IN("transfer","decision")
  AND j.ds BETWEEN "2020-11-01" AND "2020-11-30"
GROUP BY j.language, t.total_jobs
ORDER BY perc_jobs DESC;

注意主表和子查询都要加上时间和事件过滤,避免用全表总数计算占比。

方法三:修正原CTE写法

你的第二段CTE错误在于total子查询多了GROUP BY language,导致返回的是单语言数量而非总数量,修正后:

WITH CTE AS (
    SELECT language, COUNT(job_id) AS num_jobs
    FROM job_data
    WHERE event IN("transfer","decision")
      AND ds BETWEEN "2020-11-01" AND "2020-11-30"
    GROUP BY language
),
total AS (
    SELECT COUNT(job_id) AS total_jobs
    FROM job_data
    WHERE event IN("transfer","decision")
      AND ds BETWEEN "2020-11-01" AND "2020-11-30"
)
SELECT 
    c.language,
    ROUND(100.0 * c.num_jobs / t.total_jobs, 2) AS perc_jobs
FROM CTE c
CROSS JOIN total t
ORDER BY perc_jobs DESC;

内容的提问来源于stack exchange,提问作者Mir Asaduddin Adil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:42:21