在SSMS中按雇佣年份统计员工数:无需DATEPART可行吗?
按雇佣年份统计员工数的替代方案(不用DATEPART)
首先,咱们先聊聊你第二个语句出问题的原因:
- 你写的
'____-01-01 00:00:00'是无效的字符串,SQL Server没法识别这个占位符,自然会报转换错误; - 就算你把占位符换成具体年份,
GROUP BY DateOfHire也会按每个具体的日期时间分组,而不是年份,这完全不符合你的统计需求。
接下来回到你的核心需求:不用DATEPART,怎么最简统计每年雇佣人数?
方案1:用YEAR()函数(推荐,语法更简洁)
虽然YEAR()本质上是DATEPART(YEAR, DateOfHire)的简写,但它的语法更清爽,而且性能和DATEPART一样,能利用DateOfHire上的索引:
SELECT YEAR(DateOfHire) AS HireYear, COUNT(EmployeeID) AS HiredEmployees FROM Employees GROUP BY YEAR(DateOfHire)
方案2:完全不用日期函数(字符串截取)
如果你严格要求不使用任何日期相关函数,可以把日期转换成字符串后截取年份部分:
SELECT LEFT(CONVERT(varchar(10), DateOfHire, 23), 4) AS HireYear, COUNT(EmployeeID) AS HiredEmployees FROM Employees GROUP BY LEFT(CONVERT(varchar(10), DateOfHire, 23), 4)
这里CONVERT(varchar(10), DateOfHire, 23)会把smalldatetime转成YYYY-MM-DD格式的字符串,再用LEFT取前4位就是年份。不过这种方法需要做字符串转换,性能会比直接用日期函数差一点,尤其是数据量很大的时候。
关于你尝试的BETWEEN方法
如果非要用日期范围的方式统计,你得逐个年份写查询再合并,但这种方法非常繁琐,除非你有特殊需求,否则完全不推荐:
SELECT '2020' AS HireYear, COUNT(EmployeeID) AS HiredEmployees FROM Employees WHERE DateOfHire BETWEEN '2020-01-01' AND '2020-12-31 23:59:59' UNION ALL SELECT '2021' AS HireYear, COUNT(EmployeeID) AS HiredEmployees FROM Employees WHERE DateOfHire BETWEEN '2021-01-01' AND '2021-12-31 23:59:59' -- 每个年份都要写一遍,或者用动态SQL生成,反而更复杂
总结一下:最简的方法还是用YEAR()函数,既简洁又高效;如果必须完全避开日期函数,就用字符串截取的方案。
内容的提问来源于stack exchange,提问作者grrigore
相关产品推荐
相关产品推荐

