什么是SQL查询来计算平均租赁时间?

时间:2019-05-31 11:15:40

标签: sql postgresql date datetime

我需要计算按品牌分组的汽车的平均租赁时间。

为简单起见,我的数据库中有以下LEASE表:

carMake | startDateTime | endDateTime

我未完成的SQL查询如下:

SELECT lease.carMake 
FROM lease
WHERE lease.startDateTime <= {?endDate} AND lease.endDateTime >= {?startDate}
SUM ... ???
GROUP BY lease.carMake ;

示例:

carMake |   startDateTime   | endDateTime
MB        01.01.2018 00:00     01.01.2019 00:00
BMW       07.06.2018 21:00     01.01.2019 00:00
MB        06.06.2018 00:00     07.06.2018 00:00 

查询范围介于06.06.2018和07.06.2018之间的结果:

carMake | avgTime
MB        36 hours
BMW       3 hours

数据库是PostgreSQL

3 个答案:

答案 0 :(得分:1)

I'm not sure what sql you are using but in SQL Server you can do something like this

DECLARE @startdate DATETIME= '2018-06-06 00:00:00'
DECLARE @endDate DATETIME= '2018-06-07 00:00:00'


SELECT LeaseTable.CarMake, AVG(LeaseTable.LeaseHours)
FROM
(SELECT lease.carmake, 
    DATEDIFF(HH, case when lease.startDate <@startdate then @startdate else lease.startDate end, dateadd(DD, 1 ,case when lease.endDate > @endDate then @endDate else lease.endDate end)) as LeaseHours
    FROM lease
where 
    lease.startDate <= @endDate AND lease.endDate >= @startdate) as LeaseTable
GROUP BY LeaseTable.carMake 

Let me break it down a little:

SELECT carmake, AVG(LeaseHours) -- know the lease time avr by car manufacture
FROM
(Select
    LeaseInPeriod.carmake, 
    DATEDIFF(HH, LeaseInPeriod.PeriodStartDate, LeaseInPeriod.PeriodEndDate) as LeaseHours -- Know the lease time in hour
FROM
(SELECT lease.carmake, 
    case when lease.startDate <@startdate then @startdate else lease.startDate end as PeriodStartDate, -- Know the actual lease start date between the perid limits
    dateadd(DD, 1 ,case when lease.endDate > @endDate then @endDate else lease.endDate end) as PeriodEndDate -- Know the actual lease end date between the perid limits
    FROM AS lease
where 
    lease.startDate <= @endDate AND lease.endDate >= @startdate) AS LeaseInPeriod
) Leases
GROUP BY Leases.carMake 

答案 1 :(得分:1)

可以很容易地用timestamp range解决。

首先,我们计算所需时间与租赁时间之间的重叠间隔,从而可以计算出小时数的平均值:

select carmake, avg(extract(epoch from upper(duration) - lower(duration)) / 3600) as hours
from (
  select carmake, 
         tsrange(startdatetime, enddatetime, '[]') * tsrange(timestamp '2018-06-06 00:00:00', timestamp '2018-06-08 00:00:00', '[)') duration
  from lease
) t
group by carmake;

技巧是tsrange的交集运算符*

在线示例:https://rextester.com/KYXB18998

答案 2 :(得分:0)

SELECT carMake, AVG(endDateTime - startDateTime) AS avgTime WHERE startDateTime <= {?endDate} AND endDateTime >= {?startDate} FROM lease GROUP BY 1;