想要显示给定日期的上一个和下一个时隙相同日期的记录

时间:2018-09-04 07:55:54

标签: sql-server

我有一个表,其中包含针对userid和datetime字段的多个记录。用户每小时都有相同日期的可用性。

UserId         DateTime
1           2018-08-13 08:30:00 +05:30
1           2018-08-13 09:30:00 +05:30
1           2018-08-13 10:30:00 +05:30
1           2018-08-13 15:00:00 +05:30
1           2018-08-13 17:00:00 +05:30
1           2018-08-13 18:00:00 +05:30

现在,如果我要搜索日期,则假设是2018年8月13日 11:30:00 +05:30 然后我要

Previous slot = 2018-08-13 **10:30:00** +05:30

next slot = 2018-08-13 **15:00:00** +05:30

更新

快速更新我需要的日期比前一天的时间短一些。例如对于 2018-08-13 08:30:00 +05:30应该显示null为不小的可用时间。

4 个答案:

答案 0 :(得分:2)

再次尝试使用CTE,并进行了修改以匹配更改后的问题:

DECLARE @SearchDate datetime = '2018-08-13 11:30:00',
        @StartDate datetime,
        @EndDate datetime,
        @UserId int = 1;

SET @StartDate = DATETIMEFROMPARTS(YEAR(@SearchDate), MONTH(@SearchDate), DAY(@SearchDate), 0, 0, 0, 0);
SET @EndDate = DATEADD(day, 1, @StartDate);

WITH 
ctePrevious AS
(
    SELECT MAX([DateTime]) AS [DateTime] 
    FROM YourTable
    WHERE UserId = @UserId AND [DateTime] BETWEEN @StartDate AND @SearchDate
),
cteNext AS
(
    SELECT MIN([DateTime]) AS [DateTime] 
    FROM YourTable
    WHERE UserId = @UserId AND [DateTime] BETWEEN @SearchDate AND @EndDate
)
SELECT ctePrevious.[DateTime] AS prevDate, cteNext.[DateTime] AS nextDate
FROM ctePrevious, cteNext

如果在给定日期找不到条目,​​则应返回NULL值。

答案 1 :(得分:1)

您可以添加一个行号和一个自我联接。以下示例将演示其工作原理:

CREATE TABLE  #T (ID INT, DateT DATETIME)

INSERT INTO #T VALUES (1, GETDATE() - .2)
INSERT INTO #T VALUES (1, GETDATE() - .1)
INSERT INTO #T VALUES (1, GETDATE() - .05)
INSERT INTO #T VALUES (1, GETDATE())
INSERT INTO #T VALUES (1, GETDATE() + .1);


WITH CTE AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumb
    FROM #T AS T
)

SELECT C.ID, C.DateT AS StartDate, C2.DateT AS EndDate
FROM CTE AS C
LEFT JOIN CTE AS C2 ON C.RowNumb = C2.RowNumb - 1
WHERE GETDATE() BETWEEN C.DateT AND C2.DateT -- your date input here

答案 2 :(得分:0)

使用LEADLAG。这是伪SQL,但是:

SELECT DateColumn,
       LAG(DateColumn) OVER (ORDER BY DateColumn) AS Previousslot,
       LEAD(DateColumn) OVER (ORDER BY DateColumn) AS NextSlot
FROM YourTable;

与SQL_M的答案不同,这意味着您不需要对表进行2/3扫描。

答案 3 :(得分:0)

declare @wantedDate datetime = '2018-09-04 12:27:16.570'
select top 1 * from #t tP       -- Top of each min and max time
join #T tn
on tp.ID = tn.ID
and tp.DateT <= @wantedDate     -- all previous times
and tn.DateT >= @wantedDate     -- all next times
order by tp.ID, tp.DateT desc, tn.DateT

如果查询需要更新,请回复我。