Для поставленной задачи модель с вложенным множеством практически бесполезна. Я предлагаю предварительно обработать таблицу, чтобы добавить столбец материализованного пути, а затем использовать этот столбец, чтобы ответить на вопрос. Эти два шага вместе, вероятно, потребуют меньше работы, чем любое решение, основанное на представлении вложенного набора.
Поиск материализованного пути является относительно "общеизвестной" проблемой, но ваш конкретный вопрос - нет, поэтому вот запрос, основанный на путях, которые на него отвечают.
SELECT
Name,
len(MyPath)/4 AS Depth,
CASE WHEN :PathSelected LIKE MyPath + '%' THEN 1 ELSE 0 END AS Selected
FROM Category
WHERE MyPath = ''
OR (
MyPath <> ''
AND MyPath LIKE SUBSTRING(:PathSelected,1,ABS(LEN(MyPath) - 4)) + '____'
);
: PathSelected - это (SELECT MyPath FROM Categories WHERE ID =: CategorySelected)), которое можно предварительно вычислить или включить в запрос. Кроме того, АБС защищает от плана запроса, в котором SUBSTRING вычисляется, даже когда MyPath = '', и, следовательно, вызывает SUBSTRING с параметром отрицательной длины.
Вот полное описание синтаксиса SQL Server для конкретных данных, которые вы использовали в своем вопросе. В моем запросе не используются столбцы lft и rgt, поэтому я их не включил, но нет никаких причин, по которым вы не можете иметь их в своей таблице, если они служат для других целей.
create table Category(
Name varchar(25) NOT NULL,
ID int NOT NULL PRIMARY KEY,
MyPath varchar(200) NOT NULL
);
GO
insert into Category values
('ELECTRONICS',1,''),
('TELEVISIONS',2,'/001'),
('PORTABLE ELECTRONICS',3,'/002'),
('FLASH',4,'/002/001/001'),
('MP3 PLAYERS',5,'/002/001'),
('2 WAY RADIOS',6,'/002/002'),
('CD PLAYERS',7,'/002/003'),
('PLASMA',8,'/001/003'),
('LCD',9,'/001/002'),
('TUBE',10,'/001/001');
GO
DECLARE @Selected int = 7;
DECLARE @MyPath varchar(200) = (
SELECT MyPath FROM Category
WHERE ID = @Selected
);
SELECT
Name,
len(MyPath)/4 AS Depth,
CASE WHEN @MyPath LIKE MyPath + '%' THEN 1 ELSE 0 END AS Selected
FROM Category
WHERE MyPath = ''
OR (
MyPath <> ''
AND MyPath LIKE SUBSTRING(@MyPath,1,LEN(MyPath) - 4) + '____'
);
GO
DROP TABLE Category;