Sql 如何解释刷卡表中的双重条目?

Sql 如何解释刷卡表中的双重条目?,sql,sql-server-2012,ssrs-2012,Sql,Sql Server 2012,Ssrs 2012,如何解释刷卡表中的意外刷卡?我试图通过在条目上分组来选择最大值(time_cst)。这并没有解决问题。 这就是我想要它出现的方式 您可以使用LAG函数查看前一行,查看TimeATT值是否相同(按名称排序,然后按时间排序) 这要求永远不存在重叠交易的可能性。还要注意,在这个实例中,LAG函数和查询中的order by必须相同 select [Name], [TimeATT], [DateTime], case when LAG(TimeATT)OVER(order by [Name],[

如何解释刷卡表中的意外刷卡?我试图通过在条目上分组来选择最大值(time_cst)。这并没有解决问题。

这就是我想要它出现的方式


您可以使用LAG函数查看前一行,查看TimeATT值是否相同(按名称排序,然后按时间排序)

这要求永远不存在重叠交易的可能性。还要注意,在这个实例中,LAG函数和查询中的order by必须相同

  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]

然后,您可以使用此操作的结果执行所需的任何处理。一个例子是将上述内容放在一个公共表表达式中,然后使用另一个查询。请注意,您必须添加“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 = ''

您可以使用LAG函数查看前一行,查看TimeATT值是否相同(按名称排序,然后按时间排序)

这要求永远不存在重叠交易的可能性。还要注意,在这个实例中,LAG函数和查询中的order by必须相同

  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]

然后,您可以使用此操作的结果执行所需的任何处理。一个例子是将上述内容放在一个公共表表达式中,然后使用另一个查询。请注意,您必须添加“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 = ''

我已经添加了一个提琴来显示这一点,但我将在这里复制查询以供将来参考

下面是非常接近小提琴版本,只是使用临时表而不是永久表

此外,我还编辑了示例数据,因为最后两条记录上的名称之间有额外的空格。我想这是错误的

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函数需要按名称进行
分区,以避免排除
TimeATT
列在两个连续行上相同,但针对不同的人

我使用LEAD而不是LAG,因为当发现重复项时,您的样本返回了第二条“条目”记录

这可以用CTE写得更优雅,但这确实有效

这是最后的结果


我添加了一个提琴来显示这一点,但我将把查询复制到这里以供将来参考

下面是非常接近小提琴版本,只是使用临时表而不是永久表

此外,我还编辑了示例数据,因为最后两条记录上的名称之间有额外的空格。我想这是错误的

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函数需要按
名称进行
分区,以避免排除
TimeATT
列在两个连续行上相同,但针对不同的人

我使用LEAD而不是LAG,因为当发现重复项时,您的样本返回了第二条“条目”记录

这可以用CTE写得更优雅,但这确实有效

这是最后的结果


编辑您的问题,并在问题中以文本表格的形式提供示例数据和所需结果。指向外部网站的链接并不总是有效。请编辑您的问题,并在问题中以文本表的形式提供示例数据和所需结果。指向外部站点的链接并不总是有效。如何在where子句中使用Dup列?@null我更新了答案。据我所知,我必须使用CTE。如何在where子句中使用Dup列?@null我更新了答案。据我所知,我必须使用CTE。