我需要计算按品牌分组的汽车的平均租赁时间。
为简单起见,我的数据库中有以下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
答案 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的交集运算符*
。
答案 2 :(得分:0)
SELECT carMake, AVG(endDateTime - startDateTime) AS avgTime WHERE startDateTime <= {?endDate} AND endDateTime >= {?startDate} FROM lease GROUP BY 1;