T-SQL,从几个表中选择分组

时间:2013-06-04 15:59:40

标签: tsql select grouping

我的任务非常艰巨,我不知道如何开始。

让我们说我们有桌子:

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

请帮忙,:(

2 个答案:

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

SQL Fiddle

结果当然是相同的,但执行计划可能更好。