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

如何在SQL查询中按员工姓名拆分获取月度报表数据

问题描述

现有三张数据表:

Table_Project

ProjectId   ProjectName
  -------------------------
        1             A
        2             B
        3             C

Table_Employee

EmployeeId       Name  
--------------------------
    1            Jhon
    2            Jason

Table_Task

Id    ProjectId   EmployeeId    TaskName    TaskMinute    StartDate         EndDate
        ---------------------------------------------------------------------------------------
        1       1            1           xyz1           10         2024/03/17       2024/03/17
        2       2            1           xyz2           30         2024/03/17       2024/03/17
        3       1            1           xyz3           40         2024/03/17       2024/03/17
        4       2            2           kkk            90         2024/03/17       2024/03/17
        5       3            2           kk1            10         2024/03/17       2024/03/17

需求:查询EndDate属于当月的数据,按员工拆分展示,包含员工姓名、项目名、任务名、任务时长,每个员工数据末尾添加该员工的任务时长总计,期望输出格式如下:

Jhon      ProjectName   TaskName   TaskMinute   
            A           xyz1         10
            B           xyz2         30
            A           xyz3         40
                        Total        80
Jason       B           kkk          90
            C           kk1          10
                       Total        100

本人尝试使用内连接编写SQL,但未梳理出正确逻辑,尝试的SQL语句如下:

select P.ProjectName,e.Name,t.TaskMinute from Table_Task t 
inner join Table_Project p on t.projectid=p.ProjectIdId
inner join Table_Employee e on t.employeeid=e.EmployeeId
group by ProjectName,
e.Name
t.TaskMinute

请问是否可以实现上述输出,或获取包含同等信息的其他展示方式?


解决方案

一、能否实现指定格式?

可以通过SQL实现近似的结构化输出,但完全匹配你给出的缩进、姓名仅首行显示的格式,更适合在前端应用或报表工具中处理。SQL本身擅长输出规整数据集,不过可以通过拼接明细行和合计行的方式,实现包含核心信息的结构化结果。

二、具体实现方案

方案1:SQL生成带合计行的数据集

以下SQL会输出每个员工的任务明细,以及对应的合计行,通过排序确保合计行在每个员工数据的最后:

-- 任务明细行
SELECT
    e.Name AS 员工姓名,
    p.ProjectName AS 项目名,
    t.TaskName AS 任务名,
    t.TaskMinute AS 任务时长,
    1 AS sort_flag -- 标记为明细行,排序时靠前
FROM Table_Task t
JOIN Table_Project p ON t.ProjectId = p.ProjectId
JOIN Table_Employee e ON t.EmployeeId = e.EmployeeId
WHERE DATE_FORMAT(t.EndDate, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m') -- 筛选当月数据

UNION ALL

-- 员工任务时长合计行
SELECT
    e.Name AS 员工姓名,
    '' AS 项目名,
    'Total' AS 任务名,
    SUM(t.TaskMinute) AS 任务时长,
    2 AS sort_flag -- 标记为合计行,排序时靠后
FROM Table_Task t
JOIN Table_Employee e ON t.EmployeeId = e.EmployeeId
WHERE DATE_FORMAT(t.EndDate, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
GROUP BY e.Name, e.EmployeeId

-- 按员工姓名和标记排序,保证明细在前、合计在后
ORDER BY e.Name, sort_flag;

输出结果示例:

员工姓名项目名任务名任务时长
JhonAxyz110
JhonBxyz230
JhonAxyz340
JhonTotal80
JasonBkkk90
JasonCkk110
JasonTotal100

方案2:前端/报表工具处理格式

如果想要完全实现你给出的缩进、姓名仅首行显示的格式,更推荐:

  1. 用SQL查询出规整的任务明细数据(不带合计),同时单独查询每个员工的总时长
  2. 在前端页面或报表工具(如Excel、Tableau)中,通过分组显示、隐藏重复姓名、添加合计行的功能来实现目标格式。这种方式更灵活,也符合数据处理的职责划分:SQL负责取数,前端/报表负责展示格式。

三、对你尝试的SQL的修正

你写的SQL存在几个问题:

  • 关联条件错误:t.projectid=p.ProjectIdId应为t.ProjectId = p.ProjectId(多写了一个Id)
  • GROUP BY语法错误:字段之间缺少逗号,且GROUP BY的字段与SELECT字段不匹配(如需分组统计,需配合聚合函数)
  • 缺少筛选当月数据的条件

如果仅查询当月任务明细,正确的基础SQL应为:

SELECT
    e.Name AS 员工姓名,
    p.ProjectName AS 项目名,
    t.TaskName AS 任务名,
    t.TaskMinute AS 任务时长
FROM Table_Task t
JOIN Table_Project p ON t.ProjectId = p.ProjectId
JOIN Table_Employee e ON t.EmployeeId = e.EmployeeId
WHERE DATE_FORMAT(t.EndDate, '%Y-%m') = DATE_FORMAT(CURDATE(), '%Y-%m')
ORDER BY e.Name;

内容的提问来源于stack exchange,提问作者mr coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:58:28