一行中的多个记录
Multiple records in one row
我有一个 table EmpLunch,如下所示:
EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut
101 10/12/2017 9:00 AM 1:00 PM 1:30 PM 5:00 PM
101 10/13/2017 9:00 AM 1:00 PM 1:28 PM 5:00 PM
101 10/14/2017 9:00 AM 1:00 PM 1:28 PM 3:00 PM 3:28 PM 5:00 PM
101 10/15/2017 9:00 AM 5:00 PM
我需要根据以下逻辑在另一列 ErrorCode 中填充数据:
Error Code =
1 = Lunch 1 Not Taken
2 = Lunch 1 Less Than 30 Minutes
3 = Lunch 1 Started 300 Minutes Past IN Punch
4 = Lunch 2 Not Taken
5 = Lunch 2 Less Than 30 Minutes
结果 table 应该是这样的:
EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut ErrorCode
101 10/12/2017 9:00 AM 1:00 PM 1:30 PM 5:00 PM 4
101 10/13/2017 9:00 AM 1:00 PM 1:28 PM 5:00 PM 2, 4
101 10/14/2017 9:00 AM 1:00 PM 1:28 PM 3:00 PM 3:28 PM 5:00 PM 2, 5
101 10/15/2017 9:00 AM 5:00 PM 1
我写了一个简单的代码如下:
Select *,
CASE WHEN Lunch1Start IS NULL THEN '1'
WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN '2'
WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN '3'
WHEN Lunch2Start IS NULL THEN '4'
WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN '5'
END LunchError
From EmpLunch
上面的查询没有在一个单元格中给出多个记录(比如上面结果 table 中 10/13 和 10/14 的记录)。我的查询只给出列中的第一个值。请提出实现目标的方法(逗号分隔列中的多个值)。
您只需要连接三种不同情况的结果。第一个用于错误代码 1 和 2,第二个用于错误代码 3,第三个用于代码 4 和 5。像这样:
Select
*, STUFF(CASE WHEN Lunch1Start IS NULL THEN ', 1' WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN ', 2' ELSE '' END
+ CASE WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN ', 3' ELSE '' END
+ CASE WHEN Lunch2Start IS NULL THEN ', 4' WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN ', 5' ELSE '' END,1,2,'') LunchError
From EmpLunch
您可以使用连接在一起的单独 case
表达式来获取单独的值。这是一种方法:
select el.*,
stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) +
(case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, '')
from EmpLunch el;
stuff()
删除分隔符。另请注意,如果没有错误,此版本 returns 是一个空字符串,而不是 NULL
。如果你想要 NULL
,那么使用 nullif()
:
select el.*,
nullif(stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) +
(case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, ''), '')
from EmpLunch el;
请注意 datediff()
returns 是一个整数。它也可能不会完全按照您的要求执行,因为它在值之间计数 "unit boundaries"。我会改用这个逻辑:
select el.*,
stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when Lunch1Start < dateadd(minute, -30, Lunch1End) then ', 2' else '' end) +
(case when LunchEnd1 < dateadd(minute, -300) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when Lunch2End < dateadd(minute, -30, LunchI2Start) then ', 5' else '' end), 1, 2, '')
from EmpLunch el;
我的作品:
DROP TABLE IF EXISTS category --SQL 2016/17
go
CREATE TABLE Category
(id int IDENTITY (1,1) NOT NULL Primary Key
,Punchin time
,lunch1Start time
,lunch1End time
,lunch2Start time
,lunch2End time
,Punchout time
,LunchError as CASE when lunch1start is null then '1' WHEN DATEDIFF(MINUTE,lunch1start,lunch1end) < 30 THEN '2'
WHEN DATEDIFF(MINUTE,lunch1end, punchin) < 300 THEN '3'
WHEN lunch2start is null then '4' end
+ ', '+ CASE WHEN lunch2start is null then '4' WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 30 THEN '5'
WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 300 THEN '3'
END
)
INSERT category(punchin, lunch1Start, lunch1End, Punchout)
VALUES ('9:00 am','1:00 pm', '1:30 pm', '5:00 pm')
INSERT category(punchin, lunch1Start, lunch1End, Punchout)
VALUES('9:00 am','1:00 pm', '1:28 pm', '5:00 pm')
INSERT category(punchin, lunch1Start, lunch1End, lunch2Start, lunch2End, Punchout)
VALUES ('9:00 am','1:00 pm', '1:28 pm', '3:00 pm', '3:28','5:00 pm')
INSERT category(punchin, Punchout)
VALUES ('9:00 am','5:00 pm')
我有一个 table EmpLunch,如下所示:
EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut
101 10/12/2017 9:00 AM 1:00 PM 1:30 PM 5:00 PM
101 10/13/2017 9:00 AM 1:00 PM 1:28 PM 5:00 PM
101 10/14/2017 9:00 AM 1:00 PM 1:28 PM 3:00 PM 3:28 PM 5:00 PM
101 10/15/2017 9:00 AM 5:00 PM
我需要根据以下逻辑在另一列 ErrorCode 中填充数据:
Error Code =
1 = Lunch 1 Not Taken
2 = Lunch 1 Less Than 30 Minutes
3 = Lunch 1 Started 300 Minutes Past IN Punch
4 = Lunch 2 Not Taken
5 = Lunch 2 Less Than 30 Minutes
结果 table 应该是这样的:
EmployeeId BusinessDate PunchIn Lunch1Start Lunch1End Lunch2Start Lunch2End PunchOut ErrorCode
101 10/12/2017 9:00 AM 1:00 PM 1:30 PM 5:00 PM 4
101 10/13/2017 9:00 AM 1:00 PM 1:28 PM 5:00 PM 2, 4
101 10/14/2017 9:00 AM 1:00 PM 1:28 PM 3:00 PM 3:28 PM 5:00 PM 2, 5
101 10/15/2017 9:00 AM 5:00 PM 1
我写了一个简单的代码如下:
Select *,
CASE WHEN Lunch1Start IS NULL THEN '1'
WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN '2'
WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN '3'
WHEN Lunch2Start IS NULL THEN '4'
WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN '5'
END LunchError
From EmpLunch
上面的查询没有在一个单元格中给出多个记录(比如上面结果 table 中 10/13 和 10/14 的记录)。我的查询只给出列中的第一个值。请提出实现目标的方法(逗号分隔列中的多个值)。
您只需要连接三种不同情况的结果。第一个用于错误代码 1 和 2,第二个用于错误代码 3,第三个用于代码 4 和 5。像这样:
Select
*, STUFF(CASE WHEN Lunch1Start IS NULL THEN ', 1' WHEN DATEDIFF(MINUTE, Lunch1Start, Lunch1End) < 30.0 THEN ', 2' ELSE '' END
+ CASE WHEN DATEDIFF(MINUTE, LunchEnd1, PunchIn) < 300.0 THEN ', 3' ELSE '' END
+ CASE WHEN Lunch2Start IS NULL THEN ', 4' WHEN DATEDIFF(MINUTE, Lunch2End, LunchI2Start) < 30.0 THEN ', 5' ELSE '' END,1,2,'') LunchError
From EmpLunch
您可以使用连接在一起的单独 case
表达式来获取单独的值。这是一种方法:
select el.*,
stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) +
(case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, '')
from EmpLunch el;
stuff()
删除分隔符。另请注意,如果没有错误,此版本 returns 是一个空字符串,而不是 NULL
。如果你想要 NULL
,那么使用 nullif()
:
select el.*,
nullif(stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when datediff(minute, Lunch1Start, Lunch1End) < 30 then ', 2' else '' end) +
(case when datediff(minute, LunchEnd1, PunchIn) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when datediff(minute, Lunch2End, LunchI2Start) < 30 then ', 5' else '' end), 1, 2, ''), '')
from EmpLunch el;
请注意 datediff()
returns 是一个整数。它也可能不会完全按照您的要求执行,因为它在值之间计数 "unit boundaries"。我会改用这个逻辑:
select el.*,
stuff( (case when Lunch1Start is null then ', 1' else '' end) +
(case when Lunch1Start < dateadd(minute, -30, Lunch1End) then ', 2' else '' end) +
(case when LunchEnd1 < dateadd(minute, -300) < 300 then ', 3' else '' end) +
(case when Lunch2Start IS NULL then ', 4' else '' end) +
(case when Lunch2End < dateadd(minute, -30, LunchI2Start) then ', 5' else '' end), 1, 2, '')
from EmpLunch el;
我的作品:
DROP TABLE IF EXISTS category --SQL 2016/17
go
CREATE TABLE Category
(id int IDENTITY (1,1) NOT NULL Primary Key
,Punchin time
,lunch1Start time
,lunch1End time
,lunch2Start time
,lunch2End time
,Punchout time
,LunchError as CASE when lunch1start is null then '1' WHEN DATEDIFF(MINUTE,lunch1start,lunch1end) < 30 THEN '2'
WHEN DATEDIFF(MINUTE,lunch1end, punchin) < 300 THEN '3'
WHEN lunch2start is null then '4' end
+ ', '+ CASE WHEN lunch2start is null then '4' WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 30 THEN '5'
WHEN DATEDIFF(MINUTE,lunch2start,lunch2end) < 300 THEN '3'
END
)
INSERT category(punchin, lunch1Start, lunch1End, Punchout)
VALUES ('9:00 am','1:00 pm', '1:30 pm', '5:00 pm')
INSERT category(punchin, lunch1Start, lunch1End, Punchout)
VALUES('9:00 am','1:00 pm', '1:28 pm', '5:00 pm')
INSERT category(punchin, lunch1Start, lunch1End, lunch2Start, lunch2End, Punchout)
VALUES ('9:00 am','1:00 pm', '1:28 pm', '3:00 pm', '3:28','5:00 pm')
INSERT category(punchin, Punchout)
VALUES ('9:00 am','5:00 pm')