我有一张船租表:
年租:
- RentDate PK
- ReturnDate,
- BoatId
和其他不需要的字段
我需要创建一个返回四列的查询:
- 年份
- 今年的平均租赁天数
- 今年最多租用天数
- 今年最低租赁天数
现在我有这个疑问:
SELECT
YEAR(RentDate),
AVG(DATEDIFF(DD, RentDate, ReturnDate)) AS AVERAGE,
MAX(DATEDIFF(DD, RentDate, ReturnDate)) AS MAXIMUM,
MIN(DATEDIFF(DD, RentDate, ReturnDate)) AS MINIMUM
FROM RENTING
WHERE YEAR(RentDate) = YEAR(ReturnDate)
GROUP BY YEAR(RentDate)
问题在于,我正在考虑租金在年底开始的可能性,并且在另一年结束 - RentDate Year!= ReturnDate。我认为这个问题并不包含这个可能性。
答案 0 :(得分:2)
我认为此查询并未包含此可能性
不,它没有,但它很容易修复 - 只需取出你添加的WHERE
条款:
SELECT
YEAR(RentDate),
AVG(DATEDIFF(DD, RentDate, ReturnDate)) AS AVERAGE,
MAX(DATEDIFF(DD, RentDate, ReturnDate)) AS MAXIMUM,
MIN(DATEDIFF(DD, RentDate, ReturnDate)) AS MINIMUM
FROM RENTING
/*WHERE YEAR(RentDate) = YEAR(ReturnDate)*/
GROUP BY YEAR(RentDate)
即使年份发生变化, DATEDIFF
也能正常工作。
答案 1 :(得分:0)
根据您对D Stanley的回答,您希望将租期分成两年(或更长),将部分租金分配给每年。
为了做到这一点,您需要计算每年租金的天数。我知道这样做的最简单方法是使用Calendar Table。在您的情况下,您最感兴趣的是租赁的每一年。
给出一个日历表:
CREATE TABLE Calendar
([CalendarDate] date, [CalendarYear] char(4))
您将租借表加入日历,将每个租赁期限扩展到等于租赁天数的行数。您可以COUNT
按年份分组的日期,按日历年拆分租借。
SELECT RentDate, COUNT(*) AS DayCount, CalendarYear
FROM Renting INNER JOIN Calendar ON CalendarDate >= RentDate
AND CalendarDate < ReturnDate
GROUP BY RentDate, CalendarYear
包含PK RentDate
以分隔出每个不同的租赁。否则,你每年最终会得到一个数字,而无法计算你的最小值,最大值和平均值。
要获取聚合值,请将第一个查询包装在另一个查询中:
SELECT CalendarYear,
AVG(DayCount) AS AVERAGE,
MAX(DayCount) AS MAXIMUM,
MIN(DayCount) AS MINIMUM
FROM (
SELECT RentDate, COUNT(*) AS DayCount, CalendarYear
FROM Renting INNER JOIN Calendar ON CalendarDate >= RentDate
AND CalendarDate < ReturnDate
GROUP BY RentDate, CalendarYear
) AS T
这里是SQL Fiddle所以你可以看到它的实际效果。
答案 2 :(得分:0)
从表面上看,您需要在年底分割涵盖年终的租金。我会使用我喜欢的方法来调用测试驱动的查询设计(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年的部分租金。但我不打算解决这部分问题。 / p>
前三个查询需要与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