Если я запрашиваю базу данных, как я могу получить 5-ую строку из заданной строки? - PullRequest
0 голосов
/ 24 мая 2009

Если у меня есть идентификатор строки, и я хочу вернуть 5-ую строку из этой строки, как бы я это сделал?

Обычно я могу просто пойти

rowId - 5

и это будет идентификатор 5-го ряда назад ...

Однако мне нужно учитывать, если строка была удалена, это будет означать, что, например,

39, 40, 41, 42, 43, 44, 45

если бы rowId был 45, то я бы получил rowId 40 для моей 5-й строки назад, но если строка 42 была удалена, то мы бы получили ...

39, 40, 41, 43, 44, 45

и rowId 45 даст мне снова rowId 40, тогда как это должно дать мне 39 (потому что это 5-й ряд назад).

Я не могу придумать, как обойти это, я не могу изменить нумерацию идентификаторов после удаления, потому что таблица может вырасти до миллиона строк. У кого-нибудь есть идеи?

Спасибо, Matt

Ответы [ 6 ]

3 голосов
/ 24 мая 2009

Вы можете использовать функции ранжирования ROW_NUMBER T-SQL ...

Вот некоторый псевдо-SQL-код:

SELECT id, value,
   ROW_NUMBER() OVER ( ORDER BY id) AS RowNo
FROM ranking AS r1
WHERE RowNo = selectedRowNo - 5
2 голосов
/ 24 мая 2009

Построение по автоматическому ответу

select top 1 * from (
     select top 5 * from table where Id < 45 order by id desc
) as fiverows order by id asc

Это вернет 5-й ряд и только 5-й ряд.

Примечание: Выбрать * это baaaaaad, mkay? : -)

2 голосов
/ 24 мая 2009

Если вы используете Sql Server 2005 или выше, вы можете использовать ROW_NUMBER:

SELECT *
FROM (
    SELECT TOP 5
         ROW_NUMBER() OVER (ORDER BY YourId DESC) AS RowNr,
         *
    FROM YourTable
    WHERE YourId < CurrentId
    ORDER BY YourId DESC
) vw
WHERE RowNr = 5

«ORDER BY ID ASC» указывает, как вы хотите, чтобы строки были пронумерованы; Вы можете изменить его практически на любой порядок сортировки, например:

ROW_NUMBER() OVER (ORDER BY YourTimestamp DESC) AS RowNr,

Будет полезно при поиске предыдущей строки по возрасту.

1 голос
/ 24 мая 2009

Я обычно использую CTE для нумерации. Что-то вроде этого сделало бы:

;WITH NumberedRows
AS
(SELECT   ID, ROW_NUMBER() OVER(ORDER BY ID ASC) AS RowNumber
FROM      MyTable)
SELECT    ID
FROM      NumberedRows
WHERE     RowNumber = (SELECT RowNumber FROM NumberedRows WHERE ID = @MyID) - 5

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

1 голос
/ 24 мая 2009

Я понимаю, что это двойное вложение, но если вы делаете это не очень часто, и / или столбец RowNum не проиндексирован, это не должно вызвать особых проблем:

SELECT *
  FROM YourTable
 WHERE RowNum = (SELECT MIN(RowNum)
                   FROM (SELECT TOP 5 RowNum
                           FROM YourTable
                       ORDER BY RowNum DESC) t)

Кроме того, это решение будет работать и с более старыми версиями SQL, тогда как предложение "over" применимо только к 2005+.

1 голос
/ 24 мая 2009

Похоже, вы хотите вернуть 5-ю строку на основе последовательных идентификаторов (что не имеет ничего общего с физическим порядком в БД)?

Если это то, что вы хотите, и вы знаете идентификатор, с которого хотите начать, скажем, 45, вы могли бы

выберите топ 5 * из таблицы, где Id <45 упорядочено по id desc </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...