假设您的年份可能重叠(2007-2008 年,然后是 2008-2009 年),我看到的最佳选择是创建一个 Years 查找表并对其进行查询,如下所示:
SELECT m.id, m.name, COUNT(DISTINCT y.yearfield) YearCount
FROM tblmembers m
CROSS JOIN YearLookup Y
INNER JOIN tbmemberenrollment me
ON m.id = me.memberid
AND YEAR(y.yearfield) >= YEAR(me.startyear)
AND YEAR(y.yearfield) <= YEAR(me.endyear)
AND YEAR(Y.yearField) <= YEAR(GetDate())
GROUP BY m.id, m.name
SQL 小提琴演示
如果您的数据没有这些重叠的年份,那么您可以执行以下操作来获得结果:
SELECT m.id, m.name,
SUM(
CASE
WHEN YEAR(me.endyear) > YEAR(getDate())
THEN YEAR(getDate())
ELSE YEAR(me.endyear)
END - YEAR(me.startyear) + 1
) totYears
FROM tblmembers m
LEFT JOIN tbmemberenrollment me on m.id = me.memberid
WHERE YEAR(me.startyear) <= YEAR(getDate())
GROUP BY m.id, m.name
SQL 小提琴演示
编辑:使用递归 CTE 与查找表
虽然我仍然建议使用查找表,但有时这不是一个可行的选择。在这些情况下,您可以使用递归 CTE 完成同样的事情。
WITH years AS (
SELECT MAX(endyear) maxyear, MIN(startyear) minyear
FROM tbmemberenrollment
),
RecursiveCTE AS (
SELECT minyear yearfield
FROM years
UNION ALL
SELECT DATEADD(year, 1, yearfield)
FROM RecursiveCTE R
JOIN years T
ON R.yearfield < T.maxyear
)
SELECT m.id, m.name, COUNT(DISTINCT y.yearfield) YearCount
FROM tblmembers m
CROSS JOIN RecursiveCTE Y
INNER JOIN tbmemberenrollment me
ON m.id = me.memberid
AND YEAR(y.yearfield) >= YEAR(me.startyear)
AND YEAR(y.yearfield) <= YEAR(me.endyear)
AND YEAR(Y.yearField) <= YEAR(GetDate())
GROUP BY m.id, m.name