从表面上看,您需要在年底拆分覆盖年终的租金。我会使用我喜欢称之为测试驱动查询设计 (TDQD) 的方式来构建查询。
一年的租金
这可能涵盖了大部分数据:
SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) = YEAR(ReturnDate)
跨年的租金
此查询处理起始年份的租金部分:
SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, DATEFROMPARTS(YEAR(RentalDate), 12, 31)) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
这个查询处理的是下一年的租金部分:
SELECT YEAR(ReturnDate) AS RentalYear,
DATEDIFF(dd, DATEFROMPARTS(YEAR(ReturnDate), 1, 1), ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
租期超过两年
这还是比较棘手的。我要指出的是,理论上,单次租金可以从 2011-04-14 开始,到 2014-09-30 结束(为了争论),在这种情况下,2011 年有部分年租金,在 2012 年和 2013 年租了两次全年租金(但一个租了 366 天,另一个租了 365 天),然后是 2014 年的部分年租。但我不会解决这部分问题。
不带聚合的查询
前面三个查询需要结合 UNION ALL 来创建应该运行聚合的原始数据:
SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) = YEAR(ReturnDate)
UNION ALL
SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, DATEFROMPARTS(YEAR(RentalDate), 12, 31)) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
UNION ALL
SELECT YEAR(ReturnDate) AS RentalYear,
DATEDIFF(dd, DATEFROMPARTS(YEAR(ReturnDate), 1, 1), ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
聚合数据
SELECT RentalYear,
AVG(RentalDays) AS Average,
MIN(RentalDays) AS Minimum,
MAX(RentalDays) AS Maximum
FROM (SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) = YEAR(ReturnDate)
UNION ALL
SELECT YEAR(RentalDate) AS RentalYear,
DATEDIFF(dd, RentalDate, DATEFROMPARTS(YEAR(RentalDate), 12, 31)) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
UNION ALL
SELECT YEAR(ReturnDate) AS RentalYear,
DATEDIFF(dd, DATEFROMPARTS(YEAR(ReturnDate), 1, 1), ReturnDate) AS RentalDays
FROM Renting
WHERE YEAR(RentalDate) + 1 = YEAR(ReturnDate)
) AS Rentals
GROUP BY RentalYear