рассчитать время парковки на сервере sql - PullRequest
5 голосов
/ 09 мая 2019

У меня есть одно сомнение в SQL Server. Как рассчитать детали входа в систему и выхода из машины?

стол: cardetails

Здесь необходимо рассчитать для каждой машины, сколько часов проводят на стоянке.

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

Ответы [ 2 ]

1 голос
/ 09 мая 2019

вы можете попробовать это

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
0 голосов
/ 09 мая 2019

Это не совсем дает ожидаемые результаты в вашем сообщении, однако, у меня есть веские основания для того, чтобы этого не было, и я подозреваю, что ваши ожидаемые результаты неверны:

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

Обратите внимание, у меня есть 05:40:00 для автомобиля 2 на 2019-01-20. Автомобиль 2 въезжает в 20:30:10 и уезжает в 02:10:10, то есть через 5 часов и 40 минут спустя; не 05 часов 49 минут и 40 секунд спустя. если у вас есть время для ожидаемых результатов по какой-либо причине, вам нужно объяснить, почему.

Примечание: Это не будет работать, если автомобиль останется более 24 часов! Вы не ответили на мой вопрос, поэтому я предположил, что нет. Если это возможно, SQL Server не поддерживает время, превышающее 24 часа, поэтому вам лучше будет возвращать количество секунд, а ваше приложение будет отображать время более 24 часов.

...