2009-11-20 59 views
0

我有以下SQL Server查詢,我試圖從給定的Id獲取下一行和上一行。除非有兩個/更多的日期是相同的,否則所有的工作都很好,那麼我的邏輯就會崩潰。SQL Server從基於日期的表中獲取下一個前面的行

如果設置@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的下一個/上行時,請注意,重要的是,我把這個順序,日期說明,ID ASC

非常感謝

編輯:應當指出的是,這將被用於SQL Server 2005的

回答

1

你幾乎在那裏...試試這個。有效地改變日期比較是「...-或-等於對」,並告訴它不匹配當前的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 
+0

克里斯感謝這個,我努力使這項工作作爲模式是不同的。我可以看到你的建議。 – Rippo 2009-11-20 09:34:37

+0

與...不同?這應該與上面提供的示例表和數據一起工作:-)我認爲您需要將其適應於活動模式? – 2009-11-20 09:38:56

+0

我的錯誤 - 在我的SQL中有一個拼寫錯誤(在我測試它之後,爲我編譯SQL堆棧溢出以清理它)。它現在會工作......! – 2009-11-20 09:40:23

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既是prev又是next。

+0

謝謝回答但我已經運行了你的答案,並從當前4的Id中獲得6和4,如果currentId是4,我應該期望7(prev)和6(next).... – Rippo 2009-11-20 09:02:41

+0

做了一些更改。看看 – 2009-11-20 09:16:15

+0

看起來像這個釘了它。我試過<= and > =但是沒想到排除了當前的ID ...謝謝 – Rippo 2009-11-20 09:35:33

相關問題