SQL Server根据日期从表中获取下一个上一行

时间:2009-11-20 08:46:44

标签: sql-server sql-server-2005

我有以下SQL Server查询,我正在尝试从给定的ID获取下一行和上一行。一切都很好,除非有两个/更多的日期是相同的,然后我的逻辑崩溃了。

如果你设置@currentId = 4,那么我会回到上一页的id 7(它应该是id 6)

如果你设置@currentId = 6那么我会回到id 2(它应该是id 4)以便下一个

declare @t table (i int, d datetime)
insert into @t (i, d)
select 1, '17-Nov-2009 07:22:13' union
select 2, '18-Nov-2009 07:22:14' union
select 3, '17-Nov-2009 07:23:15' union
select 4, '20-Nov-2009 07:22:18' union
select 5, '17-Nov-2009 07:22:17' union
select 6, '20-Nov-2009 07:22:18' union
select 7, '21-Nov-2009 07:22:19'

--order that I want
select * from @t order by d desc, i

declare @currentId int; set @currentId = 4

--Get Prev
select TOP 1 * from @t where d > (select TOP 1 d from @t where i = @currentId order by d, i desc) order by d, i desc

--Get Next
select TOP 1 * from @t where d < (select TOP 1 d from @t where i = @currentId order by d desc) order by d desc

任何人都可以帮我解决如何保证根据给定的ID获取下一行/上一行的行为。请注意,保持此顺序,Date Desc,id ASC

非常重要

非常感谢

编辑:应该注意,这将用于SQL Server 2005.

2 个答案:

答案 0 :(得分:1)

你快到了......试试这个。有效地将日期比较更改为“ ...-或-equals-to ”并告诉它不匹配当前ID,因此它不会返回相同的行...

declare @currID int
set @currID = 4

select top 1 *
from (
    select * 
        from @t
        where d = (select d from @t where i = @currID)
            and i > @currID
    union ALL
    select * 
        from @t
        where d < (select d from @t where i = @currID)
) as t
order by d desc, i

select top 1 *
from (
    select * 
        from @t
        where d = (select d from @t where i = @currID)
            and i < @currID
    union ALL
    select * 
        from @t
        where d > (select d from @t where i = @currID)
) as t
order by d, i desc

答案 1 :(得分:0)

玩具可以尝试这样的东西

    declare @t table (i int, d datetime)
        insert into @t (i, d)
        select 1, '17-Nov-2009 07:22:13' union
        select 2, '18-Nov-2009 07:22:14' union
        select 3, '17-Nov-2009 07:23:15' union
        select 4, '20-Nov-2009 07:22:18' union
        select 5, '17-Nov-2009 07:22:17' union
        select 6, '20-Nov-2009 07:22:18' union
        select 7, '21-Nov-2009 07:22:19'

        --order that I want
        select * from @t order by d desc, i

        declare @currentId int; 
        set @currentId = 4



SELECT  TOP 1 t.*
FROM    @t t INNER JOIN
            (
                SELECT  d CurrentDateVal
                FROM    @t
                WHERE   i = @currentId
            ) currentDate ON t.d <= currentDate.CurrentDateVal AND t.i != @currentId
    ORDER BY t.d DESC

    SELECT  t.*
FROM    @t t INNER JOIN
            (
                SELECT  d CurrentDateVal
                FROM    @t
                WHERE   i = @currentId
            ) currentDate ON t.d >= currentDate.CurrentDateVal AND t.i != @currentId
    ORDER BY t.d

你必须小心,看起来6应该是上一个和下一个。