#sql #sql-server-2008
#sql #sql-server-2008
Вопрос:
Следующая проблема:
Мне нужно получить позицию записи в таблице. Допустим, у меня есть пять записей в таблице:
Name: john doe, ID: 1
Name: jane doe, ID: 2
Name: Frankie Boy, ID: 4
Name: Johnny, ID: 9
Сейчас «Фрэнки Бой» находится на третьей позиции в таблице. Но как получить эту информацию с SQL Server? Я мог бы посчитать идентификаторы, но они ненадежны, у Фрэнки идентификатор 4, но он находится на третьей позиции, потому что запись с идентификатором ‘3’ была удалена.
Есть ли способ? Я знаю о ROW_RANK, но это было бы дорого, потому что мне нужно сначала выбрать в основном весь набор, прежде чем я смогу их ранжировать row_rank.
Я использую MS SQL Server 2008 R2.
Комментарии:
1. Зачем вам нужна позиция записи? Есть ли конкретный запрос, который вы пытаетесь выполнить?
Ответ №1:
В таблицах нет ‘position’. Строки в таблице (=set) идентифицируются по значению их первичного ключа. Только результирующие строки имеют ‘position’, которая может быть детерминированной при наличии ORDER BY
предложения. Предположение, что таблицы (= наборы) имеют позицию, приведет только к проблемам и является неправильным мышлением.
Комментарии:
1. Не всегда я понимаю, что вы пытаетесь сказать, но в некоторых случаях, особенно с тем, над чем я работаю, где я экспортирую таблицу ячеек в таблицу результатов. Я хочу выделить число, основанное на условии, которое относится к определенному адресу ячейки. Мне нужно определить адрес этой ячейки перед экспортом в таблицу SQL
2. @EddyJawed: задавайте вопросы как вопросы, а не как комментарий.
Ответ №2:
Вы можете использовать row_number()
для «пометки» строк. Вы должны указать способ упорядочивания строк:
select row_number() over (order by id) as PositionInTable
, *
from YourTable
Если производительность является проблемой, вы могли бы сохранить позицию в новом столбце:
update yt1
set PositionInTable = rn
from YourTable yt1
join (
select row_number() over (order by id) as rn
, id
from YourTable
) yt2
on yt1.id = yt2.id
С включенным индексом PositionInTable
это было бы молниеносно. Но вам пришлось бы обновлять это после каждой вставки в таблицу.
Ответ №3:
Таблицы [концептуально] не упорядочены. Если вы не укажете ORDER BY в инструкции select для упорядочения набора результатов, результаты могут быть возвращены в любом порядке. Повторяющиеся выполнения одного и того же SQL могут возвращать результаты, установленные в разных порядках для каждого выполнения.
Чтобы получить номер строки в определенном результирующем наборе, используйте функцию row_number():
select row = row_number() over( order by id ) , *
from sysobjects
Это позволит присвоить номер строки каждой строке в sysobjects, как если бы таблица была упорядочена по идентификатору.
Ответ №4:
Простым способом сделать это без использования ROW_NUMBER было бы просто подсчитать, сколько строк в таблице имеют индекс, меньший или равный выбранному индексу, это дало бы номер строки.
SELECT COUNT(*) FROM YourTable WHERE ID <= 4 -- Frankie Boy, Result = 3
Возможно, это не самый эффективный способ сделать это для вашего конкретного сценария, но это простой способ добиться этого.