2014-09-04 2 views
0

У меня есть таблица с тремя полями. т.е.Получить значение из предыдущей строки/следующей строки SQL

id, transferdate, placeid 
--------------------------- 
1 | 1-4-2014 | 14 
2 | 4-4-2014 | 14 
5 | 10-4-2014| 14 
6 | 1-5-2013 | 13 
9 | 10-6-2013| 12 

Что я хотел бы достичь ... если можно ... с помощью одного запроса (не важно, сколько подзапросов), но простой SQL (без поворота, КТР и т.д.), чтобы получить то же самое: placeid's transferdate из каждой строки, в предыдущей строке или в следующую строку , чтобы я мог выполнить некоторые вычисления с ними. я имею в виду:

id, transferdate, placeid, nexttransferdate 
    -------------------------------------------- 
    1 | 1-4-2014 | 14  | 4-4-2014   
    2 | 4-4-2014 | 14  | 10-4-2014 
    5 | 10-4-2014| 14  | null (or transferdate) 
    6 | 1-5-2013 | 13  | null (or transferdate) 
    9 | 10-6-2013| 12  | null (or transferdate) 

я достиг его курсоры в хранимой процедуре или функции или даже используя временную таблицу, и я знаю, как сделать это с встроенным рекурсивными функциями (т.е. Oracle), но моя проблема заключается в том, что мне нужно использовать его в качестве подзапроса в SQL-отчете отчета, поэтому он должен быть простым SQL-кодом как один оператор.

Спасибо за ваш ответ

+0

Пожалуйста, не используйте теги, которые не относятся к вашему вопросу. –

+0

Значит, не обязательно быть агностиком? Вы отметили такое, но ваше объяснение говорит, что оно находится в sql-сервере. Предполагая, что это сервер sql, в какой версии вы работаете? И вы можете использовать cte в отчете. –

+0

@SeanLange: я отметил его как «database-agnostic», так как OP упомянул его несколько раз. Вы не знаете, о каком _report_ он имеет в виду. –

ответ

2

Стандартной функция SQL, чтобы посмотреть в предыдущие строки LAG и заглянуть в последующие строки LEAD. Тем не менее, они недоступны в каждом dbms. Просто посмотрите, доступны ли они.

Если нет: следующее значение всегда является минимальным значением всех больших значений, предыдущее значение является максимальным из всех меньших значений. Это поможет вам создать запрос.

EDIT: Вот простой запрос без LEAD для вас:

select 
    id, 
    transferdate, 
    placeid, 
    (
    select min(transferdate) 
    from transfers latertransfers 
    where latertransfers.placeid = transfers.placeid 
    and latertransfers.transferdate > transfers.transferdate 
) as nexttransferdate 
from transfers 
order by id; 

EDIT: Вот LEAD версия. Доступно в Oracle по версии 8.1.6.

select 
    id, 
    transferdate, 
    placeid, 
    lead(transferdate) over (partition by placeid order by transferdate) as nexttransferdate 
from transfers 
order by id; 
+0

Благодарим вас за ответ. он работает так же, как и в [link] (@GordonLinoff), но в плане запроса показано, что ваш браузер работает быстрее. – ckinfos

+0

Я также добавил запрос LEAD. Это прямой способ сделать это и должен привести к лучшему плану выполнения. –

1

Вы можете сделать это с автообъединение и агрегация:

select t.id, t.transferdate, t.placeid, min(t.transferdate) 
from table t left join 
    table tnext 
    on tnext.placeid = t.placeid and tnext.transferdate > t.transferdate 
group by t.id, t.transferdate, t.placeid; 

То есть, я не рекомендовал бы на самом деле, используя этот запрос. Практически в каждой базе данных есть более эффективные подходы.

+0

он работает хорошо для того, что мне нужно, но он, безусловно, делает странный план запроса, как и упоминание. я должен дать ответ на запрос кетнера. Благодарю вас обоих в любом случае. – ckinfos

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