Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
SQL 2008
имеется классическая иерархия связь ребёнок-родитель
несколько уровней


declare @TTable table(BsId int,BsParent int, BsName varchar(100))
INSERT INTO @TTable(BsId ,BsParent , BsName)
VALUES
	(1,NULL,'ROOT'),
	(2,1,'A1'),(3,1,'B1'),(4,1,'C1'),
	(5,2,'A11'),(6,2,'A12'),(7,2,'A13'),
	(8,3,'B11');
........................................


вопрос :
можно ли средствами SQL определить для каждого элемента в таблице
является ли он первым или/и последним элементом относительно иерархии на каждом уровне?

через транформацию я знаю ,что да ,но вопрос именно через SQL

Спасибо


BsID	        BsParent	        BsName	FIRSTNODE      LASTNODE	
-------------------------------------------------------------------------
1		NULL		        ROOT	1			0
2		1			A1		1			0
3		1			B1		0			0
4		1			C1		0			1
5		2			A11		1			0
6		2			A12		0			0
7		2			A13		0			1			
8		3			B11		1			0
.......................................................
10 сен 15, 12:36    [18132163]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
michael R
можно ли средствами SQL определить для каждого элемента в таблице
является ли он первым или/и последним элементом относительно иерархии на каждом уровне?
Можно.
Рекурсивное CTE + row_number() + критерий первости/последнести.
10 сен 15, 12:59    [18132325]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
Glory
Member

Откуда:
Сообщений: 104751
michael R
пасибо


BsID	        BsParent	        BsName	FIRSTNODE      LASTNODE	
-------------------------------------------------------------------------
1		NULL		        ROOT	1			0
2		1			A1		1			0
3		1			B1		0			0
4		1			C1		0			1
5		2			A11		1			0
6		2			A12		0			0
7		2			A13		0			1			
8		3			B11		1			0
.......................................................

А почему A1 первый ? Он чем то лучше В1/С1 ?
10 сен 15, 13:04    [18132351]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
Glory
michael R
пасибо


BsID	        BsParent	        BsName	FIRSTNODE      LASTNODE	
-------------------------------------------------------------------------
1		NULL		        ROOT	1			0
2		1			A1		1			0
3		1			B1		0			0
4		1			C1		0			1
5		2			A11		1			0
6		2			A12		0			0
7		2			A13		0			1			
8		3			B11		1			0
.......................................................


А почему A1 первый ? Он чем то лучше В1/С1 ?


И почему B11 не является и первым и последним одновременно на своём уровне, в прочем, как и ROOT?
10 сен 15, 13:11    [18132411]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
примерно так...
ROOT	
       (1) A1 -first
              (1)  A11 - first
              (2)  A12
              (3)  A13 - last
       (2) B1
              (1)  B11 - first+last	
       (3) C1 - last
10 сен 15, 13:16    [18132448]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
Glory
Member

Откуда:
Сообщений: 104751
michael R
примерно так...
ROOT	
       (1) A1 -first
              (1)  A11 - first
              (2)  A12
              (3)  A13 - last
       (2) B1
              (1)  B11 - first+last	
       (3) C1 - last

Ну если вы уже получили цифирки в скобокчах, то что мешает взять минимальную и максимальную из них ?
10 сен 15, 13:18    [18132460]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
with cte
as
(
select * 
from @TTable where BsParent is null
union all
select t1.*
from @TTable t1 inner join cte t2 on t1.BsParent = t2.BsId
)

select * 
, case row_number() over ( partition by bsParent order by BsName ) when 1 then 1 else 0 end as FIRSTNODE
, case row_number() over ( partition by bsParent order by BsName desc ) when 1 then 1 else 0 end as LASTNODE
from cte t
order by 2
10 сен 15, 13:18    [18132467]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Поторопился. Рекурсия тут не нужна
select
 t.BsId, t.BsParent, t.BsName,
 case when row_number() over (partition by t.BsParent order by t.BsName) = 1 then 1 else 0 end as IsFirst,
 case when row_number() over (partition by t.BsParent order by t.BsName desc) = 1 then 1 else 0 end as IsLast
from
 @TTable t;
10 сен 15, 13:30    [18132548]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
да вроде так
спасибо

Knyazev Alexey
with cte
as
(
select *
from @TTable where BsParent is null
union all
select t1.*
from @TTable t1 inner join cte t2 on t1.BsParent = t2.BsId
)

select *
, case row_number() over ( partition by bsParent order by BsName ) when 1 then 1 else 0 end as FIRSTNODE
, case row_number() over ( partition by bsParent order by BsName desc ) when 1 then 1 else 0 end as LASTNODE
from cte t
order by 2
10 сен 15, 13:30    [18132551]     Ответить | Цитировать Сообщить модератору
 Re: ребёнок-родитель определить первый-последний элемент на каждом уровне  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
invm
Поторопился. Рекурсия тут не нужна
select
 t.BsId, t.BsParent, t.BsName,
 case when row_number() over (partition by t.BsParent order by t.BsName) = 1 then 1 else 0 end as IsFirst,
 case when row_number() over (partition by t.BsParent order by t.BsName desc) = 1 then 1 else 0 end as IsLast
from
 @TTable t;


кстати, Да! нафик тут вообще СТЕ(!)
10 сен 15, 13:41    [18132641]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить