Вычесть время на основе 2 параметров - PullRequest
0 голосов
/ 26 мая 2020

У меня есть таблица в SQL Сервер

Таблица Персона

ID   Name   Date        Timer    InOrOut
----------------------------------------
1    Seth   2020-05-26  07:00   I
2    Seth   2020-05-26  17:00   O
3    Maria  2020-05-25  06:59   I
4    Maria  2020-05-25  07:00   I
5    Maria  2020-05-25  16:49   O
6    Maria  2020-05-25  17:01   O

Это мой запрос

SELECT Name As Name, Date AS Data,
case when InOrOut = 'I' then CONVERT(VARCHAR(5), CAST(Timer AS TIME), 108) end as In, 
case when InOrOut= 'U' then CONVERT(VARCHAR(5), CAST(Timer AS TIME), 108) end as Out
FROM Persona 
GROUP BY Date, Name, InOrOut, Timer ORDER BY Date DESC

И это - результат вышеприведенного запроса

Name   Date          In      Out
----------------------------------------
Seth   2020-05-26    07:00   NULL
Seth   2020-05-26    NULL    17:00
Maria  2020-05-25    06:59   NULL
Maria  2020-05-25    07:00   NULL
Maria  2020-05-25    NULL    16:49
Maria  2020-05-25    NULL    17:01

То, что я хочу спросить:

  1. Есть ли способ добавить еще один столбец с именем TotalHours , где я вычитаю Выход - Вход ? Так, как в примере Seth , это будет 17: 00 - 07: 00 , что даст результат 10 ?

Необязательно (я не Мне наплевать на точку 2 , но если бы кто-нибудь мог привести полный пример, это было бы более чем здорово)

Есть ли способ отображать только одно значение для Персона ? Как в примере Maria In 6: 59 (с наименьшим значением) и Maria Out 17: 01 (с наибольшим значением) в день?

Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Этот оператор также даст те же результаты ...

WITH cte_DistinctNameDate AS
(
    SELECT      DISTINCT [Name], [Date]
    FROM        Persona
)
SELECT      d.[Name]
            , d.[Date]
            , CONVERT ( VARCHAR(5), MIN ( p.[Timer] ), 108 ) AS [In]
            , CONVERT ( VARCHAR(5), MAX ( p.[Timer] ), 108 ) AS [Out]
            , CAST ( DATEDIFF ( MI, MIN ( p.[Timer] ), MAX ( p.[Timer] ) ) / 60.0 AS DECIMAL (4,2) ) AS [TotalHours]
FROM        cte_DistinctNameDate AS d
INNER JOIN  Persona AS p
    ON      d.[Name] = p.[Name]
    AND     d.[Date] = p.[Date]
GROUP BY    d.[Name], d.[Date]
ORDER BY    d.[Date] DESC ;

Но я думаю, что @ Zhorov более эффективен.

Или, чтобы улучшить его еще больше ...

SELECT      [Name] AS [Name]
            , [Date] AS [Data]
            , CONVERT ( VARCHAR(5), MIN ( [Timer] ), 108 ) AS [In]
            , CONVERT ( VARCHAR(5), MAX ( [Timer] ), 108 ) AS [Out]
            , CAST ( DATEDIFF ( MI, MIN ( [Timer] ), MAX ( [Timer] ) ) / 60.0 AS DECIMAL (4,2) ) AS [TotalHours]
FROM        Persona
GROUP BY    [Name], [Date]
ORDER BY    [Date] DESC ;
1 голос
/ 26 мая 2020

Возможный оператор, который возвращает ожидаемые результаты:

Таблица:

CREATE TABLE Persona (
   ID int,
   Name varchar(50),
   [Date] date,
   Timer time,
   InOrOut varchar(1)
)
INSERT INTO Persona (ID, Name, [Date], Timer, InOrOut)
VALUES
   (1, 'Seth',  '20200526', '07:00', 'I'),
   (2, 'Seth',  '20200526', '17:00', 'O'),
   (3, 'Maria', '20200525', '06:59', 'I'),
   (4, 'Maria', '20200525', '07:00', 'I'),
   (5, 'Maria', '20200525', '16:49', 'O'),
   (6, 'Maria', '20200525', '17:01', 'O')

Оператор:

SELECT 
   Name As Name, 
   Date AS Data,
   MIN(case when InOrOut = 'I' then CONVERT(VARCHAR(5), Timer, 108) end) AS [In], 
   MAX(case when InOrOut = 'O' then CONVERT(VARCHAR(5), Timer, 108) end) AS [Out],
   DATEDIFF(hour,
      MIN(case when InOrOut = 'I' then Timer end),
      MAX(case when InOrOut = 'O' then Timer end) 
   ) AS TotalHours
FROM Persona 
GROUP BY [Date], Name
ORDER BY [Date] DESC

Результат:

Name    Data        In      Out     TotalHours
Seth    2020-05-26  07:00   17:00   10
Maria   2020-05-25  06:59   17:01   11
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...