как перевести 24 часа в 12 часов в существующих данных - PullRequest
0 голосов
/ 11 июня 2019

Я хочу знать, как мой sql, как это, моя проблема заключается в том, что каждый раз, когда я удаляю свое условие where в моем коде, возникает ошибка (Преобразование не удалось при преобразовании даты и / или времени из символьной строки.) Я удаляю предложение where, потому что яхочу увидеть все мои данные, на рисунке ниже приведен только пример. У меня так много данных

Это 1-я таблица

| Entries               | recordDate              | Empid  | Reference |             
+-----------------------+-------------------------+--------+-----------+  
| 0016930507201907:35I  | 2019-05-07 00:00:00 000 | 001693 |   1693    |  
| 0016930507201917:06O  | 2019-05-07 00:00:00 000 | 001693 |   1693    |  
| 0016930507201907:35I  | 2019-05-08 00:00:00 000 | 001693 |   1693    |  
|                       | 2019-05-08 00:00:00 000 | 001693 |   1693    |

2-я таблица

| LastName | FirstName | middleName | EmployeeNO |
+----------+-----------+------------+------------+
| Cruz     | MA Kimberly  | Castillo   |   001693   |

этоесли я хочу увидеть

| Name                    | EmployeeNO | RecordDate              | TimeIn | TimeOut | 
+-------------------------+------------+-------------------------+--------+---------+
| CRUZ, MA  KIMBERLY, CASTILLO  |    001693  | 2019-05-07 00:00:00 000 |  07:35am |  05:06pm  |
| CRUZ, MA  KIMBERLY,CASTILLO   |    001693  | 2019-05-08 00:00:00 000 |  07:35am |

это мой код, пожалуйста, помогите мне заранее поблагодарить вас за вашу помощь

Select 
    B.LastName + ',' + B.FirstName + ',' + B.MiddleName[Name] ,
    A.[RecordDate],
    B.[EmployeeNO],
    CONVERT(VARCHAR(08),MIN(IIF(ISNULL(CHARINDEX('I', A.[Entries], 0), 1) > 0, CAST( SUBSTRING(A.[Entries], LEN(A.[Entries]) - 5, 5) AS [TIME]), NULL)), 100) AS [TimeIn], 
    CONVERT(VARCHAR(08),MAX(IIF(ISNULL(CHARINDEX('O', A.[Entries], 0), 1) > 0,CAST(SUBSTRING(A.[Entries], LEN(A.[Entries]) - 5, 5) AS [TIME]), NULL)),100) AS [TimeOut]
FROM Employees [B]
INNER JOIN [DTR Upload] [A] ON B.EmployeeNo = A.EmpID
GROUP BY B.LastName, B.FirstName, B.MiddleName,B.[EmployeeNO], A.[recordDate]
ORDER BY A.[recordDate] asc, B.LastName +','+B.FirstName + ','+ B.MiddleName ASC

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Это то, что вы ищете?

;WITH CTE AS
(
  SELECT EmployeeNO,
         CONCAT(LastName, ',', FirstName, ',', MiddleName) Name,
         RecordDate,
         CASE WHEN RIGHT(Entries, 1) = 'I' 
              THEN CAST(REPLACE(RIGHT(Entries, 6), 'I', '') AS TIME)
         END TimeIn,
         CASE WHEN RIGHT(Entries, 1) = 'O' 
              THEN CAST(REPLACE(RIGHT(Entries, 6), 'O', '') AS TIME)
         END TimeOut     
  FROM T1 INNER JOIN T2
  ON T1.EmpId = T2.EmployeeNO
)
SELECT EmployeeNO,
       Name,
       RecordDate,
       MIN(TimeIn) TimeIn,
       MAX(TimeOut) TimeOut
FROM CTE
GROUP BY EmployeeNO,
         Name,
         RecordDate;

Возвращает:

+------------+------------------------+-------------------------+----------+----------+
| EmployeeNO |          Name          |       RecordDate        |  TimeIn  | TimeOut  |
+------------+------------------------+-------------------------+----------+----------+
|       1693 | Cruz,Kimberly,Castillo | 2019-05-07 00:00:00 000 | 07:35:00 | 17:06:00 |
|       1693 | Cruz,Kimberly,Castillo | 2019-05-08 00:00:00 000 | 07:35:00 |          |
+------------+------------------------+-------------------------+----------+----------+

Live Demo


Теперь давайте немного поговорим о реальных проблемах, которые у вас есть.

Вы храните даты в виде строки, которая является плохой, всегда выбирайте правильный тип данных для ваших данных, чтобы вынужно хранить даты как DATE.Также для Entries имеется 3 информации, что означает отсутствие нормализации, потому что вместо этого должно быть 3 столбца.Например,

+----------------+------+---------------------+
|    Entries     | Kind |      EntriesDate    |
+----------------+------+---------------------+
| 00169305072019 |    1 | 2019-05-07 07:35:00 |
| 00169305072019 |    0 | 2019-05-07 16:30:00 |
+----------------+------+---------------------+

Таким образом, вы не попадете в эти проблемы, и все станет легко.

Для объединения имен, если вам всегда нужно получить полное имя,Я предлагаю вам использовать для этого вычисляемый столбец, тогда вам не нужно каждый раз объединять имена

ALTER TABLE <Your Table Name Here>
ADD [FullName] AS CONCAT(LastName, ',', FirstName, ',', MiddleName);
0 голосов
/ 11 июня 2019

Это работает для предоставленных вами образцов данных. Примечание однако я предполагаю , что recordDate является varchar, поскольку оно не является действительным значением datetime (если бы оно было, 2019-05-07 00:00:00 000 было бы 2019-05-07 00:00:00.000; обратите внимание на . вместо ). Если recordDate не является varchar, то вам не нужно будет включать выражения STUFF и CONVERT, чтобы "исправить" значение в операторе VALUES. Однако на самом деле вы не должны хранить данные date(time) как varchar; используйте соответствующий тип данных для ваших данных (так как эти значения не имеют временной части, кроме полуночи, date может показаться наилучшим).

Я также возвращаю столбцы TimeIn и TimeOut в качестве типа данных time. Типы данных Дата и Время в SQL Server не имеют формата, они являются двоичными значениями. Если вы хотите отобразить его в 12-часовом формате, вам необходимо настроить его на уровне представления, а не на SQL:

--Table1 Sample Data
WITH Table1 AS(
    SELECT V.Entries,
           V.recordDate,
           V.Empid,
           V.Reference
    FROM (VALUES('0016930507201907:35I','2019-05-07 00:00:00 000','001693',1693),  
                ('0016930507201917:06O','2019-05-07 00:00:00 000','001693',1693),  
                ('0016930507201907:35I','2019-05-08 00:00:00 000','001693',1693),  
                (NULL,'2019-05-08 00:00:00 000','001693',1693)) V(Entries,recordDate,Empid,Reference)),
--Table2 Sample Data
Table2 AS (
    SELECT 'Cruz' AS LastName,
           'MA Kimberly' AS FirstName,
           'Castillo' AS middleName,
           '001693' AS EmployeeNO)
--Solution
SELECT STUFF(CONCAT(', ' + T2.LastName, ', ' + T2.FirstName, ', ' + T2.middleName),1,2,'') AS [Name],
       T2.EmployeeNO,
       T1.recordDate,
       MAX(CONVERT(time(0),CASE S.InOut WHEN 'I' THEN SUBSTRING(T1.Entries,15,5) END)) AS TimeIn,
       MAX(CONVERT(time(0),CASE S.InOut WHEN 'O' THEN SUBSTRING(T1.Entries,15,5) END)) AS TimeOut
FROM Table1 T1
     JOIN Table2 T2 ON T1.Empid = T2.EmployeeNO --These should really have the same name
     CROSS APPLY(VALUES(CONVERT(datetime,STUFF(STUFF(T1.recordDate,11,1, 'T'),20,1,'.')),RIGHT(T1.Entries,1))) S(recordDate, InOut)
GROUP BY T2.EmployeeNO,
         T1.recordDate,
         T2.LastName,
         T2.FirstName,
         T2.middleName;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...