我的任务非常艰巨,我不知道如何开始。
让我们说我们有桌子:
Car
- CarId (int)
- OperatorId (int)
- ProductionDate (date)
Person
- PersonId (int)
- Name (vchar)
CarRentHistory
- HistoryId (int)
- CarFk (int)
- OperatorFk (int)
- ChangeDate (date)
每辆车总是租用的。生产日期是第一次出租。
一个人可以租几辆车,但每辆车在一瞬间只能有一个操作员。
问题是如何选择每个人和每辆车的数据(按人和车划分)平均租金时间。
Example:
Person1:
- PersonId = 1,
- Name = Bill,
Person2:
- PersonId = 2,
- Name = Max,
Car1:
- CarId = 1,
- Operator = 1,
- ProductionDate = 2013/1/1,
CarRentHistory:
- HistoryId=1, CarFk=1, OperatorFk=1, Date = 2013/1/1
- HistoryId=2, CarFk=1, OperatorFk=2, Date = 2013/2/2
- HistoryId=3, CarFk=1, OperatorFk=1, Date = 2013/3/3
因此,Car1由Person1(按生产)租用2013/1/1,然后mont稍后Person2租用(2013/2/2)。
结果应该是这样的:
Bill,Car1,Average =((2013/2/2 - 2013/1/1)+(NOW - 2013/3/3))/ 2
Max,Car1,Average =(2013/3/3 - 2013/2/2)/ 1
请帮忙,:(
答案 0 :(得分:1)
第一步是找出每个租期的长度。为此,请执行相关子查询,以查找与开始日期一起的结束日期。如果我们没有找到一行,这意味着租金是最新的,今天的日期将是结束日期(我假设)。一旦你有了每个租赁的长度,这是一个简单的问题,按人和车分组并取平均值。
以下是完整查询:
with RentalLengths as (
select P.Name, H.CarFk,
datediff(Day, ChangeDate,
isnull((
select min(ChangeDate)
from CarRentHistory H2
where H2.CarFk = H.CarFk
and H2.ChangeDate > H.ChangeDate
), CURRENT_TIMESTAMP)) as Length
from CarRentHistory H
inner join Person P on P.PersonId = H.OperatorFk
)
select Name, CarFk, AVG(Length)
from RentalLengths
group by Name, CarFk
Here是一个SQL小提琴,显示正在运行的查询。
答案 1 :(得分:0)
如果使用SQL Server 2012,则可以充分利用新的LEAD窗口函数。它将为您提供下一行列的值,这使得构建每个租用期的对非常有用。
这个想法与Chad Henderson的回答相同:首先构建对,然后计算平均值。
with RentalPeriod as (
select
CarFk, OperatorFk, ChangeDate,
lead(ChangeDate) over (partition by CarFk order by ChangeDate) as NextChangeDate
from CarRentHistory
)
select
CarFk, OperatorFk,
avg(datediff(day,
ChangeDate,
isnull(NextChangeDate, getdate()))) as AverageDays
from RentalPeriod
group by CarFk, OperatorFk
结果当然是相同的,但执行计划可能更好。