查询获取每年两个日期之间的平均天数,最大值和最小天数值

时间:2014-10-23 21:22:30

标签: sql max average min datediff

我有一张船租表:
年租:
- 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。我认为这个问题并不包含这个可能性。

3 个答案:

答案 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