Самостоятельное соединение, чтобы вычесть customer_out_time строки из customer_in_time следующей строки - PullRequest
0 голосов
/ 11 июля 2020

Приведенный ниже запрос был написан, чтобы предоставить официанту свободное время между двумя последовательными клиентами (для первого клиента дня это будет 0, а затем просто вычесть customer_out_time из следующего customer_in_time. Где, поскольку запрос дает неправильный результат, как он даже суммирует значения. Я не могу обнаружить ошибку. Есть предложения?

Я не могу использовать задержку, поскольку мой sql сервер - это 2008

Вывод запроса

+------------------------------------------------------------------+  
| Name              Customer_In_Time         Customer_Out_Time    Free Time                 |  
+------------------------------------------------------------------+  
| Nikhil, Tiwari    2020-03-03 14:30:00.000   2020-03-03 15:11:00.000   0    |  
| Ayish, Jain       2020-03-03 08:10:00.000   2020-03-03 08:35:46.650   0    |  
| Ayish, Jain       2020-03-03 08:33:12.000   2020-03-03 09:35:02.000   -2   |  
| Ayish, Jain       2020-03-03 09:22:00.000   2020-03-03 10:30:19.447   47   |  
| Ayish, Jain       2020-03-03 11:54:24.000   2020-03-03 13:44:07.000   199  |  
| Ayish, Jain       2020-03-03 14:16:04.000   2020-03-03 16:23:01.000   341  |  
| Harsh,Gupta       2020-03-03 07:34:52.000   2020-03-03 08:48:47.000   0    |  
| Harsh,Gupta       2020-03-03 10:30:31.000   2020-03-03 11:48:26.000   102  |  
| Harsh,Gupta       2020-03-03 12:37:43.000   2020-03-03 13:35:43.000   229  |  
+------------------------------------------------------------------+  

Требуемый вывод для свободного времени:

0

0

-2 -13 84 32 0 102

Declare @start date, @end date
set @start='01/01/2020'
set @end='03/03/2020'

select Waiter,t.Customer_In_Time,Customer_Out_Time,
       coalesce(sum(datediff(minute, prev_cot, Customer_in_time)), 0) as free_minutes
from (select t.*,
             tprev.Customer_out_time as prev_cot
      from t outer apply
           (select top (1) t2.*
            from t t2
            where t2.Waiter = t.Waiter and t2.date = t.date and
                  t2.Customer_in_time < t.Customer_in_time
                  
            order by t.Waiter, t2.Customer_in_time 
           ) tprev
     ) t
     where t.date between @start and @end
     and Waiter is not Null
     and Room_no not like '%TH%'
    
group by Waiter, Customer_In_Time,Customer_Out_Time
order by t.Waiter,t.Customer_In_time 

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

Похоже, вы хотите lag():

select t.*,
       datediff(minute,
                lag(Customer_Out_Time, 1, Customer_Out_Time) over (partition by waiter order by Customer_In_Time) as prev_cot
                Customer_In_Time
               ) as diff_minutes
from t;
0 голосов
/ 11 июля 2020

Единственная проблема с вашим кодом заключается в том, что он обрабатывает только первую строку как предыдущую для всей группы, но нам нужно выбрать только предыдущую строку, поэтому нам нужна функция нумерации для создания чисел в группах и выбора только последняя строка.

Мы можем использовать ROW_NUMBER() для создания номеров записей для каждого официанта, а затем легко выбрать предыдущую строку на основе значения rn.

select t.waiter, t.Customer_In_Time, t.Customer_Out_Time
 , row_number() over (partition by t.waiter order by t.waiter, t.Customer_In_Time) rn
into #temp 
from @t t

См. Db <> fiddle здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...