Выбор предыдущего и следующего ряда с помощью sp - PullRequest
0 голосов
/ 23 ноября 2011

Я хочу выбрать предыдущую и следующую строку из таблицы на основе текущего идентификатора. Я отправляю текущий идентификатор в хранимую процедуру и использую этот запрос:

-- previous
select top 1 id from table where id < @currentId order by id desc
-- next
select top 1 id from table where id < @currentId order by id asc

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

Можно ли решить эту проблему в sql без дополнительных запросов?

Ответы [ 2 ]

2 голосов
/ 23 ноября 2011

Вы можете использовать вложенный top.Пример для вашего "следующего ряда".

SELECT TOP 1 *
FROM   (SELECT TOP 2 *
        FROM   YourTable
        WHERE  id >= @currentId
        ORDER  BY id) T
ORDER  BY id DESC  

и для "предыдущего ряда"

SELECT TOP 1 *
FROM   (SELECT TOP 2 *
        FROM   YourTable
        WHERE  id <= @currentId
        ORDER  BY id DESC) T
ORDER  BY id ASC  
1 голос
/ 23 ноября 2011

Редактировать - только что понял, что вы всегда хотите, чтобы две строки были возвращены, переработать ...

Обновленный код:

SELECT * FROM @t WHERE ID = (   select top 1 id 
                                from @t 
                                where id < 
                                    case 
                                        when exists (select id from @t where id < @ID) 
                                        then @ID 
                                        else (@ID + 1) 
                                    end 
                                order by id desc
                            )

UNION

SELECT * FROM @t WHERE ID = (   select top 1 id 
                                from @t 
                                where id > 
                                    case 
                                        when exists (select id from @t where id > @ID) 
                                        then @ID 
                                        else (@ID - 1) 
                                    end 
                                order by id
                            )

Оригинальный пост ниже, прежде чем я понял, что именно вы хотели

Вы были очень близки, вам нужен оператор UNION и одно небольшое изменение синтаксиса для вашего запроса.

SELECT * FROM [table] WHERE ID = (select top 1 id from @t where id < @ID order by id desc)
UNION
SELECT * FROM [table] WHERE ID = (select top 1 id from @t where id > @ID order by id)

Это вернет 1 строку, если переданный вами идентификатор - это первая или последняя строка, в противном случае - 2 строки.

Тестовый код:

DECLARE @t TABLE
(
    Id int identity,
    Col varchar(200)
)

INSERT INTO @t VALUES('column one')
INSERT INTO @t VALUES('column two')
INSERT INTO @t VALUES('column three')
INSERT INTO @t VALUES('column four')
INSERT INTO @t VALUES('column five')

DELETE FROM @t WHERE ID = 3

DECLARE @Id int
SET @Id = 3 -- Change this to other values to further test

SELECT * FROM @t WHERE ID = (select top 1 id from @t where id < @ID order by id desc)
UNION
SELECT * FROM @t WHERE ID = (select top 1 id from @t where id > @ID order by id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...