问题描述
样本数据:
SELECT * from trips;
trip_id | driver_id | pickup_timestamp | dropoff_timestamp
---------+-----------+---------------------+----------------------
1 | 1 | 2020-01-01 8:00 AM | 2020-01-01 9:00 AM
2 | 1 | 2020-01-01 8:30 AM | 2020-01-01 9:30 AM
3 | 2 | 2020-01-01 9:00 AM | 2020-01-01 10:30 AM
4 | 2 | 2020-01-01 9:30 AM | 2020-01-01 11:30 AM
5 | 2 | 2020-01-01 10:30 PM | 2020-01-02 12:30 AM
编写一个T-SQL查询,该查询计算特定日期每位驾驶员中至少一名乘客在驾驶员车辆中的工作时间。
查询参数:
date = '2020-01-01'
预期结果:
driver_id | work_time
----------+-----------
1 | 1:30:00
2 | 4:00:00
评论:
-
1号驱动程序从8:00 AM到9:30 AM正常工作。结束工作时间为1h30m。
-
2号驱动程序从当天的9:00 AM到11:30 AM以及从10:30 PM到12:00 AM工作,导致2h30m + 1h30m = 4h的工作时间。
这是我尝试过的
select driverid as 'DriverID',format(Max(dropoff_timestamp)-min(pickup_timestamp),'hh:mm') as 'Working Hour'
from trips where convert(date,pickup_timestamp)='2020-01-01'
group by driverid
但此查询未提供特定结果DriverID工作时间1 01:30 2 03:30
解决方法
您可以使用以下查询。
这也是一个link实用演示。
说明:
initialsetfordate部分定义了一组从所需日期开始的记录。它还会修剪dropoff_timestamp列,以将其值限制为当天结束。我们还可以使用Lead函数获取下一条记录的值。
下一个连续集将在每行中使用上一个集合中的超前值,并将其与当前下降时间戳进行比较,以将时间戳中的最小值作为较高的时间范围。
最后,我们按驾驶员分组,并对每个记录的日期范围的时差求和。
; with initialsetfordate as
(
select
driver_id,pickup_timestamp,dropoff_timestamp =
case
when cast(dropoff_timestamp as date)<> cast(pickup_timestamp as date)
then cast(cast(dropoff_timestamp as date)as datetime)
else dropoff_timestamp
end,new_dropoff_timestamp =
ISNULL(lead(pickup_timestamp) over(partition by driver_id order by pickup_timestamp asc),dropoff_timestamp)
from trips
where cast(pickup_timestamp as date)='2020-01-01'
),continuousset as (
select
driver_id,dropoff_timestamp=
case
when dropoff_timestamp>= new_dropoff_timestamp
then new_dropoff_timestamp
else dropoff_timestamp
end
from initialsetfordate
)
select driver_id,CONVERT(varchar(12),DATEADD(minute,sum(datediff(mi,dropoff_timestamp)),0),114) time_worked from continuousset
group by driver_id
,
这是我的解决方案,我创建了一个SQL函数,该函数以driverID作为参数,它将返回每个驾驶员的总时数。
CREATE FUNCTION Fn_getTotalHours
(
-- Add the parameters for the function here
@drive_ID int
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @TotalHours INT
-- Add the T-SQL statements to compute the return value here
--Gets the hour difference bettween the 2 dates
--And return the sum for each driver
SELECT @TotalHours=SUM(DATEDIFF(hour,dropoff_timestamp))
from trips
Group BY driver_ID
-- Return the result of the function
RETURN @TotalHours
END
GO
用法
select distinct driver_id,dbo.Fn_getTotalHours(driver_id) as TotalHours
from trips