[英]How does this aggregated query find the correct values
我在理解此代码时遇到了麻烦。 它实际上似乎可行,但是我不明白如何“找到”活动年和月的正确值以获得正确的最小和最大? 还是运行所有排列的最高排列? 这对我来说很奇怪。
我确实了解dateadd的工作原理,而不是查询实际上如何整体工作。 这可能是一个不好的问题,因为我实际上并不需要解决问题的帮助,只需了解其工作原理即可。
select
EmployeeNumber,
sum(BaseCalculation) as BaseCalculation,
min(dateadd(mm, (ActivityYear - 1900) * 12 + ActivityMonth - 1 , 0)) as StartDate,
max(dateadd(mm, (ActivityYear - 1900) * 12 + ActivityMonth - 1 , 0)) as EndDate
from
Compensation
where
1=1
-- and
group by
EmployeeNumber
它将ActivityYear
和ActivityMmonth
列转换为日期。 它通过计算自1900年以来的月份数并将其添加到零时间来实现。 因此,2000年1月将变成100年1月。这似乎是一个非常不可思议的计算,因为大约有2,000年历史的日期并没有真正的用处。
当然,这假定ActivityYear
是可识别的最近一年。
我可以将年份和月份转换为该月初的第一天,如下所示:
min(cast(cast(ActivityYear * 10000 + ActivityMonth + 1 as varchar(255)) as date)
Sql Server将计算该语句的每个值,然后仅返回最小值和最大值。
尽管我不能肯定地说sql server在内部执行这种方式,但是考虑到我的方式,我想象引擎剥离了group by和所有聚合函数,然后运行该查询。 然后仅求和/查找最小值。
对于min
和max
函数调用,算法为
dateadd(mm, (ActivityYear - 1900) * 12 + ActivityMonth - 1 , 0)
您的查询使用此算法从“ Compensation
表计算所有可能的日期。 然后,将最小日期选择为StartDate
,将最大日期选择为EndDate
。
这就是返回正确的最大和最小的方式。
请注意,dateadd签名为DATEADD (datepart , number , date )
由于最后一个参数为0,因此会将算法计算出的数字加到month(mm),然后返回从0开始的相应日期。
请查看此以获取更多信息: https : //msdn.microsoft.com/en-us/library/ms186819.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.