如何计算刷卡 table 中的重复条目?
How to account for double entries in a card swipe table?
如何计算刷卡中的意外刷卡 table?我尝试通过在输入时将它们分组来选择 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
您可以使用 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
然后您可以使用此结果进行任何需要的处理。一个例子是将上面的内容放在一个常见的 table 表达式中并使用另一个查询。请注意,您必须添加 "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 = ''
我添加了一个 fiddle 来展示这个工作,但我会在此处复制查询以供将来参考。
http://www.sqlfiddle.com/#!18/87593fe/12/0
下面非常接近 fiddle 版本,只是使用临时 table 而不是永久 table.
另外,我编辑了示例数据,因为最后两条记录的名称之间有额外的空格。我认为这是错误的。
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
Name 以避免排除行
TimeATT
连续两行的列相同,但针对不同的人。
我使用 LEAD 而不是 LAG,因为您的样本在发现重复项时返回了第二条 "Entry" 记录。
这可以用 CTE 写得更优雅,但这确实有效。
这是最终结果..
如何计算刷卡中的意外刷卡 table?我尝试通过在输入时将它们分组来选择 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
您可以使用 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
然后您可以使用此结果进行任何需要的处理。一个例子是将上面的内容放在一个常见的 table 表达式中并使用另一个查询。请注意,您必须添加 "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 = ''
我添加了一个 fiddle 来展示这个工作,但我会在此处复制查询以供将来参考。
http://www.sqlfiddle.com/#!18/87593fe/12/0
下面非常接近 fiddle 版本,只是使用临时 table 而不是永久 table.
另外,我编辑了示例数据,因为最后两条记录的名称之间有额外的空格。我认为这是错误的。
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
Name 以避免排除行
TimeATT
连续两行的列相同,但针对不同的人。
我使用 LEAD 而不是 LAG,因为您的样本在发现重复项时返回了第二条 "Entry" 记录。
这可以用 CTE 写得更优雅,但这确实有效。
这是最终结果..