如何在工作时间创建SQL查询

问题描述

样本数据:

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...