【问题标题】:left join to previous record in same table based on datetime column根据日期时间列左连接到同一表中的上一条记录
【发布时间】:2016-07-18 01:19:12
【问题描述】:

我有一个表格,其中包含会员访问时间的详细信息。

我想根据日期时间列对同一表中的前一条记录进行左连接

当我查看访问数据时,我还想查看他们上次访问的时间,这样我就可以计算访问之间的时间间隔。 VisitDateTime 列是日期时间数据类型。该表中可能有数亿行。

示例数据:

MemberID VisitDateTime
1        2016-01-01 10:00:00.000
2        2016-01-01 10:01:00.000
1        2016-01-01 11:00:00.000
2        2016-01-01 11:30:00.000
3        2016-01-01 11:45:00.000
1        2016-01-01 11:50:00.000

所以我正在尝试将一个表重新加入到自身上,该成员之前的 Visit.VisitDateTime 显示为 PreviousVisitDateTime 列:

期望的结果:

MemberID VisitDateTime           PreviousVisitDateTime
1        2016-01-01 10:00:00.000 null
2        2016-01-01 10:01:00.000 null
1        2016-01-01 11:00:00.000 2016-01-01 10:00:00.000
2        2016-01-01 11:30:00.000 2016-01-01 10:01:00.000
3        2016-01-01 11:45:00.000 null
1        2016-01-01 11:50:00.000 2016-01-01 11:00:00.000

但我什至无法想象我会如何去做。

【问题讨论】:

  • 您使用的是什么版本的 SQL Server?

标签: sql-server left-join


【解决方案1】:

您无需指定 SQL Server 的版本,因此对于 SQL Server 2012 及更高版本:

CREATE TABLE #Test (MemberID INT, VisitDateTime DATETIME);

INSERT INTO #Test(MemberID, VisitDateTime) VALUES
(1, '2016-01-01 10:00:00.000'),
(2, '2016-01-01 10:01:00.000'),
(1, '2016-01-01 11:00:00.000'),
(2, '2016-01-01 11:30:00.000'),
(3, '2016-01-01 11:45:00.000'),
(1, '2016-01-01 11:50:00.000') 

SELECT MemberID
      ,VisitDateTime,
      LAG(VisitDateTime) OVER (PARTITION BY MemberID ORDER BY VisitDateTime) PreviousVisit FROM #Test
      ORDER BY VisitDateTime;


  MemberID    VisitDateTime           PreviousVisit
----------- ----------------------- -----------------------
1           2016-01-01 10:00:00.000 NULL
2           2016-01-01 10:01:00.000 NULL
1           2016-01-01 11:00:00.000 2016-01-01 10:00:00.000
2           2016-01-01 11:30:00.000 2016-01-01 10:01:00.000
3           2016-01-01 11:45:00.000 NULL
1           2016-01-01 11:50:00.000 2016-01-01 11:00:00.000

要模拟2008年的LAG,试试Alternate of lead lag function in sql server 2008

【讨论】:

【解决方案2】:

如果你想用左连接来做:

SELECT a.MemberID, a.Visitdatetime,MIN(b.visitdatetime)
FROM #Test a
LEFT JOIN #Test b on b.MemberID=a.MemberID and b.visitDateTime < a.visitDateTime
GROUP BY a.MemberID,a.VisitDateTime
ORDER BY a.visitdatetime

【讨论】:

  • 感谢 David,这行得通,但是跨 200K 记录需要几分钟,而 LAG / PARTITION 解决方案不到 1 秒。
  • 我知道这不是最佳解决方案。在发布此之前,我看到了另一个答案(更好)。我只是想我应该提到它,因为您最初的问题专门询问了左连接逻辑:-)
猜你喜欢
  • 1970-01-01
  • 2020-03-29
  • 2021-08-20
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多