繁体   English   中英

此汇总查询如何找到正确的值

[英]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

它将ActivityYearActivityMmonth列转换为日期。 它通过计算自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和所有聚合函数,然后运行该查询。 然后仅求和/查找最小值。

对于minmax函数调用,算法为

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM