我想知道我的sql这样的问题,我的问题是每当我删除代码中的where子句时都会出现错误(从字符串转换日期和/或时间时转换失败。)我删除了where子句,因为我要查看我的所有数据,下图仅是示例,我有这么多数据
这是第一张桌子
| 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 |
第二张桌子
| 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
答案 0 :(得分:0)
这适用于您提供的示例数据。 注意,但是,我假设 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;
答案 1 :(得分:0)
那是你的追随吗?
;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 | |
+------------+------------------------+-------------------------+----------+----------+
现在,让我们谈谈您遇到的实际问题。
您将日期存储为字符串是不好的,请始终为数据选择正确的数据类型,因此您需要将日期存储为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);