如何处理刷卡表中的意外刷卡?我尝试通过将其分组来选择max(time_cst)。它没有解决问题。 http://www.sqlfiddle.com/#!18/06cc8/2
EmpID Enter/Exit Time
2999 Entry 06:00AM
2999 Entry 06:01AM
2999 Exit 12:00PM
2999 Entry 01:00PM
2999 Exit 03:00PM
2999 Entry 04:00PM
2999 Exit 06:00PM
这就是我希望它显示的方式。 http://www.sqlfiddle.com/#!18/5cfbb/2
EmpID EntryTime ExitTime
2999 06:01AM 12:00PM
2999 01:00PM 03:00PM
2999 04:00PM 06:00PM
答案 0 :(得分:1)
您可以使用LAG函数查看上一行,并查看TimeATT值是否相同(按名称排序,然后按时间排序)。
这要求交易不可能重叠。另外请注意,在这种情况下,LAG函数中的顺序和查询中的顺序必须相同。
select [Name], [TimeATT], [DateTime],
case when LAG(TimeATT)OVER(order by [Name],[DateTime]) = TimeATT then 'Dup'
else ''
end as Dup
from Table1
order by [Name],[DateTime]
http://www.sqlfiddle.com/#!18/06cc8/14/0
然后可以使用此结果执行所需的任何处理。一个示例是将以上内容放入公共表表达式中,然后使用另一查询。请注意,您必须添加“ TOP XXX”才能获得在CTE中工作的订单,因此我们必须强制执行此操作,因为数据是必需的。
WITH DupsMarked as (
select top 100 PERCENT [Name], [TimeATT], [DateTime],
case when LAG(TimeATT)OVER(order by [Name],[DateTime]) = TimeATT then 'Dup'
else ''
end as Dup
from Table1
order by [Name],[DateTime]
)
SELECT * FROM DupsMarked where Dup = ''
答案 1 :(得分:1)
我添加了一个小提琴来显示此功能,但我将在此处复制查询以供将来参考。
http://www.sqlfiddle.com/#!18/87593fe/12/0
下面的内容非常接近小提琴版本,只是使用了临时表而不是永久表。
我还编辑了示例数据,因为最后两个记录的名称之间有多余的空格。我认为这是错误的。
DROP TABLE IF EXISTS #Table1
CREATE TABLE #Table1
([Name] varchar(9), [TimeATT] int, [DateTime] varchar(19))
;
INSERT INTO #Table1
([Name], [TimeATT], [DateTime])
VALUES
('jane doe', 1, '2019-04-23T08:00:00'),
('jane doe', 1, '2019-04-23T08:01:01'),
('jane doe', 2, '2019-04-23T12:00:00'),
('jane doe', 1, '2019-04-23T12:05:00'),
('john doe', 1, '2019-04-23T08:00:00'),
('john doe', 2, '2019-04-23T09:00:01'),
('john doe', 1, '2019-04-23T09:05:00'),
('john doe', 2, '2019-04-23T12:00:00')
SELECT [Name],[EntryTime], [ExitTime]
FROM ( -- sub query to get matching exit time for each entry if it exists
SELECT
[Name],
[DateTime] as EntryTime,
LEAD([DateTime], 1, NULL) OVER(PARTITION BY [Name] ORDER BY [DateTime]) AS ExitTime
,TimeATT, [DateTime]
FROM ( -- subquery to exclude duplicate records
SELECT * FROM ( -- subquery to identify records to ignore
SELECT
[Name], [TimeATT], [DateTime],
CASE LEAD(TimeATT, 1, 0) OVER(PARTITION BY [Name] ORDER BY [DateTime])
WHEN TimeATT THEN 1
ELSE 0
END AS Exclude
FROM #Table1) a
WHERE Exclude = 0
) t
) z
WHERE [TimeATT] = 1 -- filter so left column is always entry time.
ORDER BY [Name], [DateTime]
注意:LEAD函数需要使用partitioned by
的名称,以避免在
TimeATT
列在连续的两行中相同,但适用于不同的人。
我用LEAD代替了LAG,因为当发现重复时,您的样本返回了第二条“ Entry”记录。
使用CTE可以写得更优雅,但这确实有用。
这是最终结果。