2010-02-02 3 views
4

Я хочу иметь возможность get следующей и предыдущей строки с использованием SQLite.SQLite выберите следующую и предыдущую строку на основе предложения 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 

Например:

Учитывая идентификатором 46 Я хотел бы вернуть идентификаторы (предыдущий) и (следующий)

Учитывая идентификатор 160 Я хотел бы вернуть идентификаторы (предыдущий) и (следующий один) и т.д ...

Знайте, что данные упорядочены по statusId then dateCreated DESC и ИМЕЕТ работать с использованием SQLite.

select * from @t order by statusId, dateCreated desc 

Тестовые данные, созданные в SQL сервере ...

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+ это будет довольно тривиально!

EDIT:

Вот тот же самый сценарий тестовых данных, но и для 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 146 к 46

ответ

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

Превосходно, пару небольших модов, но это работает как шарм! – Rippo

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

не заказано по идентификатору, оно упорядочено по статусу и дате. Rippos не сказал, что при последовательном заказе идентификатор является последовательным. –

+1

@zapping, Id не является последовательным, это моя проблема. Извините, но это неверно. – Rippo

Смежные вопросы