2010-02-02 56 views
4

我希望能夠使用SQLite在下一行和前一行執行getSQLite根據Where子句選擇下一行和前一行

id statusid date 
168 1 2010-01-28 16:42:27.167 
164 1 2010-01-28 08:52:07.207 
163 1 2010-01-28 08:51:20.813 
161 1 2010-01-28 07:10:35.373 
160 1 2010-01-27 16:09:32.550 
46 2 2010-01-30 17:13:45.750 
145 2 2010-01-30 17:13:42.607 
142 2 2010-01-30 16:11:58.020 
140 2 2010-01-30 15:45:00.543 

例如:

鑑於ID 46我想返回的ID (前一個)和(下一個)

鑑於ID 160我想退回ids (上一個)和(下一個一個) 等等

注意,該數據由statusId then dateCreated DESC有序,HAS使用SQLite工作。在SQL Server中創建

select * from @t order by statusId, dateCreated desc 

測試數據...

set nocount on; set dateformat ymd; 
declare @t table(id int, statusId int, dateCreated datetime) 
insert into @t 
select 168,1,'2010-01-28 16:42:27.167' union 
select 164,1,'2010-01-28 08:52:07.207' union 
select 163,1,'2010-01-28 08:51:20.813' union 
select 161,1,'2010-01-28 07:10:35.373' union 
select 160,1,'2010-01-27 16:09:32.550' union 
select 46,2,'2010-01-30 17:13:45.750' union 
select 145,2,'2010-01-30 17:13:42.607' union 
select 142,2,'2010-01-30 16:11:58.020' union 
select 140,2,'2010-01-30 15:45:00.543' 

使用SQL Server 2005 +,這將是相當微不足道!

編輯:

這是同樣的測試數據腳本但SQLite的這是問題的焦點。

create table t (id int, statusId int, dateCreated datetime); 
insert into t 
select 168,1,'2010-01-28 16:42:27.167' union 
select 164,1,'2010-01-28 08:52:07.207' union 
select 163,1,'2010-01-28 08:51:20.813' union 
select 161,1,'2010-01-28 07:10:35.373' union 
select 160,1,'2010-01-27 16:09:32.550' union 
select 46,2,'2010-01-30 17:13:45.750' union 
select 145,2,'2010-01-30 17:13:42.607' union 
select 142,2,'2010-01-30 16:11:58.020' union 
select 140,2,'2010-01-30 15:45:00.543'; 

EDIT 2請注意,數據是不是一個很好的例子,所以我必須改變id 14646

回答

2

這個問題是一個複雜得多比它第一次出現。字段的兩個順序必須分別處理,然後與工會組合,並獲得適當的結果。爲了獲得上一個和下一個,我們需要另一個工會,所以我們最終得到一個與子工會的聯盟。

這適用於提供的數據。我測試了很多輸入並獲得了正確的前/後輸出。使用時,請確保您取得所有146的實例。

SELECT * 
FROM 
(
    SELECT t1.* 
    FROM t t1, 
      (
       SELECT * 
       FROM t 
       WHERE id = 146 
      ) t2 
    WHERE t1.statusid = t2.statusid 
     AND t1.dateCreated >= t2.dateCreated 
     AND t1.id <> 146 

    UNION 

    SELECT t1.* 
    FROM t t1, 
      (
       SELECT * 
       FROM t 
       WHERE id = 146 
      ) t2 
    WHERE t1.statusid < t2.statusid 


    ORDER BY    
      t1.statusid DESC, 
      t1.dateCreated 

    LIMIT 1 
) 

UNION 

SELECT * 
FROM 
(
    SELECT t1.* 
    FROM t t1, 
      (
       SELECT * 
       FROM t 
       WHERE id = 146 
      ) t2 
    WHERE t1.statusid = t2.statusid 
     AND t1.dateCreated <= t2.dateCreated 
     AND t1.id <> 146 

    UNION 

    SELECT t1.* 
    FROM t t1, 
      (
       SELECT * 
       FROM t 
       WHERE id = 146 
      ) t2 
    WHERE t1.statusid > t2.statusid 


    ORDER BY    
      t1.statusid, 
      t1.dateCreated DESC 

    LIMIT 1 
) 

ORDER BY    
     statusid, 
     dateCreated DESC 
; 
+0

非常棒,幾個小小的MODS,但它的作品就像一個魅力! – Rippo 2010-02-02 17:04:45

0
select id from theTable where id>@id order by id desc limit 1 
union 
select id from theTable where id<@id order by id desc limit 1 
+0

它不是按ID排序的,它是按狀態和日期排序的。當這樣排序時,Rippos沒有說id是連續的。 – 2010-02-02 13:14:09

+1

@zapping,這個Id不是順序的,這是我的問題。對不起,但這是不正確的。 – Rippo 2010-02-02 13:16:49