SQL按日期分组避免重复 计算月度员工累计总数问题咨询
问题根因
你遇到的计数翻倍问题核心原因是关联表存在一对多关系:D.Employee的单行数据会和SuperAdmin.Customer、D.RegisteredUser表的多条记录匹配,导致员工数据被重复展开,统计时同一员工被多次计数。小范围筛选指定CompanyId时关联表无重复数据所以结果正常,全量查询时重复数据暴露就出现翻倍误差。
正确实现方案
关联表前先做去重处理,同时用员工唯一ID做去重计数,双重保障统计准确性:
SELECT Dates2, -- 当月全量员工总数(和你给出的预期输出格式一致) SUM(month_emp_cnt) AS Total_Employees -- 如果需要统计从最早日期到当前月的累计员工总数,用下面这行替换上面的SUM即可 -- SUM(SUM(month_emp_cnt)) OVER (ORDER BY Dates2 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Accumulated_Total FROM ( -- 先按公司+月份维度统计单公司月度符合条件的员工数 SELECT ISNULL(EOMONTH(ER.TCTimestamp), EOMONTH(SC.GoLiveDate)) AS Dates2, EE.CompanyId, -- 按员工唯一ID去重计数,即使有重复关联也不会多算 COUNT(DISTINCT CASE WHEN EE.EmployeeStatusId IN ('0','1','2') THEN EE.EmployeeId END) AS month_emp_cnt FROM D.Employee EE -- SC表先按CompanyId去重,避免单公司多条记录导致重复关联 INNER JOIN ( SELECT DISTINCT CompanyId, GoLiveDate FROM SuperAdmin.Customer ) AS SC ON SC.CompanyId = EE.CompanyId -- ER表先按RegisteredUserId去重,避免单用户多条记录导致重复关联 LEFT JOIN ( SELECT DISTINCT RegisteredUserId, TCTimestamp FROM D.RegisteredUser ) AS ER ON EE.RegisteredUserId = ER.RegisteredUserId -- 需要筛选指定公司时打开下面注释即可 -- WHERE SC.CompanyId IN (76,79) GROUP BY ISNULL(EOMONTH(ER.TCTimestamp), EOMONTH(SC.GoLiveDate)), EE.CompanyId ) AS company_month_stat GROUP BY Dates2 ORDER BY Dates2 DESC
以上方案移除了原代码中无意义的Name分组、外层多余的te分组逻辑,完全匹配你给出的统计规则和输出要求。
内容的提问来源于stack exchange,提问作者Fazza
相关产品推荐
相关产品推荐

