在sql server中计算停车时间

时间:2019-05-09 11:37:42

标签: sql-server sql-server-2012

我在sql server中有一个疑问。如何计算汽车登录和注销时间的详细信息?

表格:菜豆

这里需要计算每辆车在停车场花费多少小时。

creatE TABLE [dbo].[CarDetails](
    [carid] [int] NULL,
    [DateTimeDetail] [datetime] NULL,
    [Flag] [varchar](50) NULL
) 
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (1, CAST(N'2019-01-20T19:05:00.000' AS DateTime), N'in')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (1, CAST(N'2019-01-20T22:30:00.000' AS DateTime), N'out')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (2, CAST(N'2019-01-20T20:30:10.000' AS DateTime), N'in')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (2, CAST(N'2019-01-21T02:10:10.000' AS DateTime), N'out')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (3, CAST(N'2019-01-23T07:07:40.000' AS DateTime), N'in')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (3, CAST(N'2019-01-23T10:50:40.000' AS DateTime), N'out')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (3, CAST(N'2019-01-23T11:00:10.000' AS DateTime), N'in')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (3, CAST(N'2019-01-23T14:15:30.000' AS DateTime), N'out')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (2, CAST(N'2019-01-21T08:20:10.000' AS DateTime), N'in')
GO
INSERT [dbo].[CarDetails] ([carid], [DateTimeDetail], [Flag]) VALUES (2, CAST(N'2019-01-21T10:20:10.000' AS DateTime), N'out')
GO

这些是记录:

carid   DateTimeDetail              Flag
1       2019-01-20 19:05:00.000     in
1       2019-01-20 22:30:00.000     out
2       2019-01-20 20:30:10.000     in
2       2019-01-21 02:10:10.000     out
3       2019-01-23 07:07:40.000     in
3       2019-01-23 10:50:40.000     out
3       2019-01-23 11:00:10.000     in
3       2019-01-23 14:15:30.000     out
2       2019-01-21 08:20:10.000     in
2       2019-01-21 10:20:10.000     out

基于上述数据,我希望输出如下:

carid | DateTimeDetails | Totaltime(hh:mm:ss)
  1     |2019-01-20       | 03:25:00
  2     |2019-01-20       | 05 :49:40
  2     |2019-01-21       | 02:00:00
  3     |2019-01-23       | 06:58:20

我尝试如下

select a.carid ,  sum(datediff(mm,b.datetimedetail,a.datetimedetail))as totalmm from  CarDetails a join  CarDetails b
on a.carid=b.carid

where a.datetimedetail<=(select max(c.[DateTimeDetail]) from CarDetails c join CarDetails a on a.carid=c.carid
)
group by a.carid 

请告诉我如何编写查询以在sql server中实现此任务

2 个答案:

答案 0 :(得分:1)

您可以尝试

select carid,dateIn, cast(DATEADD(ms, SUM(DATEDIFF(ms, '00:00:00.000', timeout)), '00:00:00.000') as time) timeOut 
from (
    select carid,cast([DateTimeDetail]as DATE) DateIn , 
        (select top 1 [DateTimeDetail] 
            from [CarDetails] b 
            where b.carid=a.carid and b.[DateTimeDetail]>a.[DateTimeDetail] and flag='out' )
        -[DateTimeDetail] timeOut
from [CarDetails] a
where Flag='in') c
group by  carid,dateIn

这给出了以下结果:

carid   dateIn  timeOut
1   2019-01-20  03:25:00.0000000
2   2019-01-20  05:40:00.0000000
2   2019-01-21  02:00:00.0000000
3   2019-01-23  06:58:20.0000000

答案 1 :(得分:0)

这在您的帖子中并没有给您预期的结果,但是,我有充分的理由不这样做,并且我怀疑您的预期结果是错误的:

--Because, from experience, people can somehow enter things twice before exiting...
WITH Grp AS(
    SELECT CD.carid,
           CD.DateTimeDetail,
           CD.Flag,
           COUNT(CASE Flag WHEN 'Out' THEN 1 END) OVER (PARTITION BY carid ORDER BY CD.DateTimeDetail ASC
                                                        ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS Grp
    FROM dbo.CarDetails CD),
InOut AS(
    SELECT carid,
           MIN(CASE Flag WHEN 'In' THEN Grp.DateTimeDetail END) AS TimeIn,
           MAX(CASE Flag WHEN 'Out' THEN Grp.DateTimeDetail END) AS [TimeOut]
    FROM Grp
    GROUP BY carid, grp)
SELECT carid,
       CONVERT(date,TimeIn) AS DateTimeDetails,
       CONVERT(time(0),DATEADD(SECOND,SUM(DATEDIFF(SECOND,TimeIn, [TimeOut])),'00:00:00')) AS TotalTime
FROM InOut
GROUP BY carid,
         CONVERT(date,TimeIn)
ORDER BY carid ASC;

这给出了以下结果:

carid       DateTimeDetails TotalTime
----------- --------------- ----------------
1           2019-01-20      03:25:00
2           2019-01-20      05:40:00
2           2019-01-21      02:00:00
3           2019-01-23      06:58:20

请注意,我在2019年1月20日有一辆05:40:00的汽车2。轿厢2在20:30:10进入并在02:10:10离开,这是5小时40分钟后;不是05小时49分40秒之后。如果您有时间在预期结果中是有原因的,则需要说明原因。

注意: 如果汽车停留超过24小时,则此方法将无效!您没有回答我的问题,所以我认为没有。如果可以,SQL Server不支持超过24小时的时间,因此最好返回秒数,并使应用程序显示24小时以上的时间。