将具有日期时间值的行与同一张表进行比较

时间:2019-05-13 18:43:31

标签: sql tsql

首先,提到我没有直接访问数据库的权限可能会有所帮助。我工作的软件具有使用SQL的内置报告功能,因此它确实限制了我可以做的某些事情(并且使做简单的事情变得非常困难)。无论如何,这是我的情况。我有一个包含这样的行的表:

ClientVisit_ID   Client_ID   Time_In                 Time_Out
440222           12345       5/6/2019 9:45:00 AM     5/6/2019 9:59:00 AM
440195           12345       5/6/2019 10:00:00 AM    5/6/2019 12:30:00 PM
440523           54321       5/6/2019 11:45:00 AM    5/6/2019 12:59:00 PM
440775           54321       5/6/2019 12:58:00 PM    5/6/2019 1:30:00 PM

前两行都很好,第2行的Time_In大于第1行的Time_Out。我只想查看第3和第4行的结果,其中第4行的Time_In小于第Time_Out行3.这些行在数据库中也可能不是顺序的,但是Client_ID列将匹配。

我尝试使用LAG,但是我必须在查询中丢失某些内容,因为它仅返回一些结果并且缺少我想查看的几行。我以前从未使用过它,所以我一无所知。

SELECT CV1.*,
CV2.rev_timein
FROM ClientVisit AS CV1
INNER JOIN (
  SELECT
      *,
      CASE WHEN CVG.prev_rev_timeout >= rev_timein 
        AND CVG.prev_client_id = client_id
        THEN 0 ELSE 1 END AS island_start_ind
  FROM
  (SELECT
      ROW_NUMBER() OVER(ORDER BY client_id, rev_timein, rev_timeout) AS RN,
      clientvisit_id,
      client_id,
      rev_timein,
      rev_timeout,
      LAG(rev_timeout,1) OVER (ORDER BY client_id, rev_timein, rev_timeout) AS prev_rev_timeout,
      LAG(client_id,1) OVER (ORDER BY client_id, rev_timein, rev_timeout) AS prev_client_id
  FROM ClientVisit

  ) AS CVG) 
AS CV2 ON CV1.client_id = CV2.client_id AND 
             CV1.clientvisit_id != CV2.clientvisit_id AND
             CV1.rev_timein = CV2.rev_timein AND
             CV2.island_start_ind = 1

比较这些行以发现重叠时间的最理想方法是什么?我还希望看到两行重叠,使用上面的代码,我仅得到一行,而不是两行(但是正如我提到的,我缺少几行,我知道是重叠的。)

很抱歉本文上的任何格式设置问题,在这里我只问了几个问题。希望它不会太混乱。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

如果您只想检索同一客户端的行,而rev_timein在另一个ClientVisit的timein和timeout之间,则此SQL应该这样做:

SELECT CV1.*, CV2.rev_time_in, CV2.rev_timeout
FROM ClientVisit AS CV1
INNER JOIN ClientVisit AS CV2
ON CV1.Client_ID = CV2.CLient_ID AND CV1.ClientVisit_ID <> CV2.ClientVisit_ID
WHERE CV2.rev_timein BETWEEN CV1.rev_timein and CV1.rev_timeout
OR CV2.rev_timeout BETWEEN CV1.rev_timein and CV1.rev_timeout
ORDER BY CV1.ClientVisit_ID

… 

OR, 

ORDER BY CV1.Client_ID, CV1.rev_timein

答案 1 :(得分:0)

尝试一下:

select ClientVisit_ID,Client_ID,Time_In,Time_Out 
from (
select *, 
LAG(time_Out,1) OVER (partition by client_id order by time_in) pre_out, 
LEAD(time_in,1) over(partition by client_id order by time_in) next_in
from ClientVisit)a
where a.Time_Out > a.next_in or a.Time_In < a.pre_out

测试结果(我在示例中又添加了一行以对其进行测试):

DB<>Fiddle