Что такое SQL-запрос для расчета среднего времени аренды? - PullRequest
0 голосов
/ 31 мая 2019

Мне нужно рассчитать среднее время аренды моих автомобилей, сгруппированных по марке.

Для простоты у меня есть следующая таблица 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 ]

1 голос
/ 31 мая 2019

Это можно решить с помощью диапазона отметок времени довольно легко.

Сначала мы рассчитываем интервал перекрытия между требуемым временем и временем аренды, из которого мы можем вычислить среднее значение в часах:

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;

Хитрость заключается в том, что оператор пересечения * дляЦарство

Онлайн пример: https://rextester.com/KYXB18998

1 голос
/ 31 мая 2019

Я не уверен, какой sql вы используете, но в SQL Server вы можете сделать что-то вроде этого

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 

Позвольте мне немного разобрать это:

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 
0 голосов
/ 31 мая 2019
SELECT carMake, AVG(endDateTime - startDateTime) AS avgTime WHERE startDateTime <= {?endDate} AND endDateTime >= {?startDate} FROM lease GROUP BY 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...