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

能否通过单条SQL查询获取多维度服务台工单统计数据?

一次性搞定服务台多维度工单统计的SQL优化方案

嘿,你现在在做服务台的指标统计,要拿每个用户的总工单数、超7天和超30天的未结工单数,不用重复跑三次SQL啦!用条件聚合的方式就能一次查询搞定所有数据,效率和可读性都能提升不少。

先给你两种可行的写法,你可以根据自己的习惯选:

方法一:用JOIN关联表直接统计

SELECT
    u.user_login AS UserName,
    COUNT(*) AS 总工单数,
    -- 统计超7天的工单:符合条件记1,否则0,求和就是数量
    SUM(CASE WHEN DATEDIFF(day, COALESCE(i.created_on, s.created_on), GETDATE()) > 7 THEN 1 ELSE 0 END) AS 超7天工单数,
    -- 同理统计超30天的工单
    SUM(CASE WHEN DATEDIFF(day, COALESCE(i.created_on, s.created_on), GETDATE()) > 30 THEN 1 ELSE 0 END) AS 超30天工单数
FROM
    [fpscdb008_system].[asgnmt] a
JOIN
    [fpscdb008_system].[app_user] u ON u.app_user_id = a.app_user_id
-- 关联事件工单表,过滤未关闭的记录
LEFT JOIN
    [fpscdb008_ws_004].[incidents] i 
    ON i.id = a.item_id 
    AND a.item_defn_id = 12610 
    AND i.soft_delete_id = 0 
    AND i.status_1 NOT IN ('Closed','Resolved','Cancelled')
-- 关联服务请求表,同样过滤未关闭的记录
LEFT JOIN
    [fpscdb008_ws_004].[service_request] s 
    ON s.id = a.item_id 
    AND a.item_defn_id = 7861 
    AND s.soft_delete_id = 0 
    AND s.status_1 NOT IN ('Closed','Resolved','Cancelled')
-- 确保只统计有对应工单的分配记录
WHERE
    i.id IS NOT NULL OR s.id IS NOT NULL
GROUP BY
    u.user_login
ORDER BY
    u.user_login;

方法二:用CTE先合并所有工单再统计

这种方式逻辑更清晰,把所有未关闭的工单先合并成一个数据集,再做统计:

WITH AllOpenTickets AS (
    -- 先取所有未关闭的事件工单
    SELECT
        u.user_login AS UserName,
        i.created_on AS CreatedDate
    FROM
        [fpscdb008_system].[asgnmt] a
    JOIN
        [fpscdb008_system].[app_user] u ON u.app_user_id = a.app_user_id
    JOIN
        [fpscdb008_ws_004].[incidents] i 
        ON i.id = a.item_id 
        AND a.item_defn_id = 12610
    WHERE
        i.soft_delete_id = 0 
        AND i.status_1 NOT IN ('Closed','Resolved','Cancelled')
    -- 用UNION ALL保留所有记录,避免UNION自动去重导致数据丢失
    UNION ALL
    -- 再取所有未关闭的服务请求工单
    SELECT
        u.user_login AS UserName,
        s.created_on AS CreatedDate
    FROM
        [fpscdb008_system].[asgnmt] a
    JOIN
        [fpscdb008_system].[app_user] u ON u.app_user_id = a.app_user_id
    JOIN
        [fpscdb008_ws_004].[service_request] s 
        ON s.id = a.item_id 
        AND a.item_defn_id = 7861
    WHERE
        s.soft_delete_id = 0 
        AND s.status_1 NOT IN ('Closed','Resolved','Cancelled')
)
-- 基于合并后的数据集做多维度统计
SELECT
    UserName,
    COUNT(*) AS 总工单数,
    SUM(CASE WHEN DATEDIFF(day, CreatedDate, GETDATE()) > 7 THEN 1 ELSE 0 END) AS 超7天工单数,
    SUM(CASE WHEN DATEDIFF(day, CreatedDate, GETDATE()) > 30 THEN 1 ELSE 0 END) AS 超30天工单数
FROM
    AllOpenTickets
GROUP BY
    UserName
ORDER BY
    UserName;

几个关键点说明:

  • 条件聚合:核心就是用CASE WHEN配合SUM()(或COUNT())来实现分组内的多维度统计,不用重复执行多次查询。
  • UNION ALL vs UNION:一定要用UNION ALL,因为UNION会自动去重,如果有重复的工单记录(比如同一工单多次分配)会被过滤掉,导致统计不准。
  • 时间计算:用DATEDIFF(day, CreatedDate, GETDATE())直接计算工单创建至今的天数差,比CreatedDate <= GETDATE() - 30更直观,逻辑是一致的。

这样你跑一次SQL就能拿到所有需要的指标,不用重复操作,还能减少数据库的查询压力~

内容的提问来源于stack exchange,提问作者Brian Susol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:27:17