Суммируйте дату двух таблиц, сравните их и верните новый столбец на основе сравнения

РЕШЕНО:

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

SELECT * FROM 
(SELECT SUM(CASE WHEN DATEPART(YEAR, t.inStampDate) > 2018  THEN 1 ELSE 0 END) AS 'Stamps',
ISNULL(t.inStampDate, '') as 'inStampDate',
 t.employeeID
FROM dbo.timeRecording t
WHERE DATEPART(YEAR, t.inStampDate) > 2018
GROUP BY t.employeeID,
     t.inStampDate ) inStamp

INNER JOIN

(SELECT SUM(CASE WHEN DATEPART(YEAR, t.outStampDate) > 2018  THEN 1 ELSE 0 END) AS 'Stamps',
ISNULL(t.outStampDate, '') as 'outStampDate',
t.employeeID
FROM dbo.timeRecording t
WHERE DATEPART(YEAR, t.outStampDate) > 2018
GROUP BY t.employeeID,
     t.outStampDate ) outStamp

ON inStamp.inStampDate = outStamp.outStampDate AND inStamp.employeeID = outStamp.employeeID

Предыдущая ситуация:

Ситуация: у меня есть пользователи, которые могут войти или выйти из системы. Эти значения регистрируются. Теперь я хочу показать, как часто пользователь входил или выходил в общей сложности за один день.

У меня есть таблица, в которой у меня есть два значения даты StampInDate и StampOutDate. Также есть employeeID. Я попытался подсчитать общее количество входящих и исходящих марок за один день. Я уже могу показать общее количество марок для каждой входящей или исходящей марки, но я не могу зайти так далеко, чтобы сравнить эти значения и создать новый столбец «totalStampsThatDay», который будет заполнен количеством марок в этот день. Сообщение об ошибке, которое я получаю:

Сообщение 8120, уровень 16, состояние 1, строка 17 Столбец «dbo.timeRecording.employeeID» недопустим в списке выбора, так как он не содержится ни в агрегатной функции, ни в предложении GROUP BY.

Код, который работает:

SELECT t.employeeID,
DATEPART(YEAR, t.inStampDate) AS 'InYear',                
DATEPART(MONTH, t.inStampDate) AS 'InMonth',              
DATEPART(DAY, t.inStampDate) AS 'InDay',
DATEPART(YEAR, t.outStampDate) AS 'OutYear',                  
DATEPART(MONTH, t.outStampDate) AS 'OutMonth',            
DATEPART(DAY, t.outStampDate) AS 'OutDay',
COUNT(t.inStampDate) AS 'StampIns',
COUNT( t.outStampDate) AS 'StampOuts'
FROM dbo.timeRecording t

GROUP BY  DATEPART(DAY, t.inStampDate),
          DATEPART(MONTH, t.inStampDate),
          DATEPART(YEAR, t.inStampDate),
          DATEPART(DAY, t.outStampDate),
          DATEPART(MONTH, t.outStampDate),
          DATEPART(YEAR, t.outStampDate),
          t.employeeID
ORDER BY t.employeeID

Теперь я пытаюсь отредактировать его, чтобы добиться того, чего хочу, но не удалось:

SELECT tr.StampIns,
tr.StampOuts,
tr.eID,
t.employeeID,
DATEPART(YEAR, t.inStampDate) AS 'InYear',                
DATEPART(MONTH, t.inStampDate) AS 'InMonth',              
DATEPART(DAY, t.inStampDate) AS 'InDay',
DATEPART(YEAR, t.outStampDate) AS 'OutYear',                  
DATEPART(MONTH, t.outStampDate) AS 'OutMonth',            
DATEPART(DAY, t.outStampDate) AS 'OutDay'

FROM dbo.timeRecording t
JOIN
    (SELECT 
        COUNT(tr.inStampDate) AS 'StampIns',
        COUNT(tr.outStampDate) AS 'StampOuts',
        tr.employeeID as 'eID'
        FROM dbo.timeRecording tr
    ) tr ON tr.eID = t.employeeID

GROUP BY  DATEPART(DAY, t.inStampDate),
          DATEPART(MONTH, t.inStampDate),
          DATEPART(YEAR, t.inStampDate),
          DATEPART(DAY, t.outStampDate),
          DATEPART(MONTH, t.outStampDate),
          DATEPART(YEAR, t.outStampDate),
          t.employeeID,
          tr.eID,
          tr.StampIns,
          tr.StampOuts

ORDER BY t.employeeID

Что-то типа:

employeeID | date    | totalStampsThatDay
1          | 21.11.19| 2
2          | 21.11.19| 0
3          | 22.11.19| 1
1          | 22.11.19| 1

... и так далее

---- ОБНОВЛЕНИЕ ---- Почти получил то, что хотел. Мне нужно только добавить столбец для даты, например. 2019-11-19, но я не могу сделать это прямо сейчас.

SELECT t.employeeID,
COUNT(t.inStampDate)  + COUNT( t.outStampDate) as 'TotalStamps',
SUM(CASE WHEN DATEPART(YEAR, t.inStampDate) > 2018  THEN 1 ELSE 0 END) AS 'StampIns',
SUM(CASE WHEN DATEPART(YEAR, t.outStampDate) > 2018  THEN 1 ELSE 0 END) AS 'StampOuts'
FROM dbo.timeRecording t
WHERE DATEPART(YEAR, t.inStampDate) > 2018 OR DATEPART(YEAR, t.outStampDate) > 2018 
GROUP BY t.employeeID

Мой вывод до сих пор:

 employeeID | Total | In | Out
 7          | 9     | 6  | 3
 8          | 105   | 48 | 57
 11         | 6     | 5  | 1

И хотите:

employeeID | Date       | Total | In | Out
7          | 2019-11-19 | 2     | 1  | 1
7          | 2019-11-20 | 3     | 2  | 1
11         | 2019-11-19 | 1     | 1  | 0
11         | 2019-11-16 | 2     | 1  | 1 

person drecunion    schedule 07.11.2019    source источник
comment
Итак, какова цель GROUP BY без какой-либо агрегации?   -  person Eric    schedule 08.11.2019


Ответы (1)


SELECT t.employeeID,
    DATEPART(YEAR, t.inStampDate) AS 'InYear',                
    DATEPART(MONTH, t.inStampDate) AS 'InMonth',              
    DATEPART(DAY, t.inStampDate) AS 'InDay',
    DATEPART(YEAR, t.outStampDate) AS 'OutYear',                  
    DATEPART(MONTH, t.outStampDate) AS 'OutMonth',            
    DATEPART(DAY, t.outStampDate) AS 'OutDay',
    COUNT(t.inStampDate)  + COUNT( t.outStampDate) as 'TotalStamps',
FROM dbo.timeRecording t

GROUP BY  DATEPART(DAY, t.inStampDate),
          DATEPART(MONTH, t.inStampDate),
          DATEPART(YEAR, t.inStampDate),
          DATEPART(DAY, t.outStampDate),
          DATEPART(MONTH, t.outStampDate),
          DATEPART(YEAR, t.outStampDate),
          t.employeeID
ORDER BY t.employeeID

Что насчет этого?

person ben92    schedule 07.11.2019
comment
Извините за поздний ответ, все работает, спасибо за это. Только одна проблема. Иногда у меня есть значение по умолчанию, то есть 1900-01-01, могу ли я как-то отфильтровать эти значения? Что-то вроде COUNT(IF ( t.inStampDate › 2000-01-01 ? t.inStampDate : 0) ? - person drecunion; 19.11.2019
comment
вы можете добавить предложение WHERE или HAVING, чтобы пропустить эти значения. - person ben92; 20.11.2019