Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
туплю что-то
with cte as
(
select id
		,ref
		,0 lvl
		,parentid
from objects 
where parentid is null
union all
select o.id
		,o.ref
		,lvl+1
		,o.parentid
from objects o 
join cte c 
on o.parentid=c.id
)
select c.* 
from cte c 

возвращает

id ref lvl parentid
1 184 0 NULL
2 185 1 1
3 186 1 1
4 187 1 1
6 188 2 2
7 189 2 2
8 190 2 2
9 90 3 6


а вот как переписать, чтобы запись с id=9 явилась сразу после своего родителя?
22 авг 15, 21:03    [18055299]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
waszkiewicz
а вот как переписать, чтобы запись с id=9 явилась сразу после своего родителя?
Для любого "порядка" при выводе нужно испоьзовать сортировку.

В данном случае можно в CTE сформировать строку с ID через разделитель, и сортировать по ней.
22 авг 15, 21:52    [18055455]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
alexeyvg
waszkiewicz
а вот как переписать, чтобы запись с id=9 явилась сразу после своего родителя?
Для любого "порядка" при выводе нужно испоьзовать сортировку.

В данном случае можно в CTE сформировать строку с ID через разделитель, и сортировать по ней.
Сортировать строки из чисел с разделителями и надеяться на хоть какой-то порядок? Ну-ну... :)
23 авг 15, 11:02    [18056354]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
Alexander Titkin
Member

Откуда: Москва
Сообщений: 91
sphinx_mv
Сортировать строки из чисел с разделителями и надеяться на хоть какой-то порядок? Ну-ну... :)


Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.
\1
\1\2
\1\2\6
\1\2\6\9
\1\2\7
\1\2\8
\1\3
\1\4
23 авг 15, 11:36    [18056384]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
alexeyvg,
так вроде?
with cte as
(
select 
		id
		,ref
		,0 lvl
		,parentid
		,convert(nvarchar(max),id) root
from objects 
where parentid is null
union all
select o.id
		,o.ref
		,c.lvl+1
		,o.parentid
		,convert(nvarchar(max),c.root)+'/'+convert(nvarchar,o.id)
from objects o 
join cte c 
on o.parentid=c.id
)
select c.* 
		,p.name
from cte c
join parts p
on c.ref=p.id
order by root
23 авг 15, 12:00    [18056410]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Alexander Titkin
sphinx_mv
Сортировать строки из чисел с разделителями и надеяться на хоть какой-то порядок? Ну-ну... :)


Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.
\1
\1\2
\1\2\6
\1\2\6\9
\1\2\7
\1\2\8
\1\3
\1\4
Лучше использовать STR(ID,10) вместо ID (если тип int).
И разделитель в этом случае не понадобится,
ибо все ID будут выровнены по правому краю и иметь одинаковую длину
благодаря автоматическому дополнению пробелами слева.
Можно спокойно сортировать по такой строке.
23 авг 15, 12:38    [18056449]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
Alexander Titkin
sphinx_mv
Сортировать строки из чисел с разделителями и надеяться на хоть какой-то порядок? Ну-ну... :)


Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.
\1
\1\2
\1\2\6
\1\2\6\9
\1\2\7
\1\2\8
\1\3
\1\4
А кто-то даст свой любимый зуб, что парент ВСЕГДА будет иметь код меньше, чем у дитенка? :)
23 авг 15, 13:43    [18056536]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
[quot sphinx_mv]
Alexander Titkin
пропущено...
Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.

Для "целей ТСа" необходимо и достаточно использовать ORDER BY по составному ключу - Level, ParentId, ChildId (заменить на нужные имена по смыслу)
23 авг 15, 13:54    [18056549]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 27985
sphinx_mv
Alexander Titkin
пропущено...


Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.
\1
\1\2
\1\2\6
\1\2\6\9
\1\2\7
\1\2\8
\1\3
\1\4
А кто-то даст свой любимый зуб, что парент ВСЕГДА будет иметь код меньше, чем у дитенка? :)
А этого и не нужно.
23 авг 15, 14:37    [18056605]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
Alexander Titkin
Member

Откуда: Москва
Сообщений: 91
[quot sphinx_mv]
sphinx_mv
пропущено...

Для "целей ТСа" необходимо и достаточно использовать ORDER BY по составному ключу - Level, ParentId, ChildId (заменить на нужные имена по смыслу)

Хоть отрицательные числа, хоть гуиды, хоть строки- по барабану. А вот свое предложение вы проверьте, явно ведь фигню написали.

ps: за вариант с разделителем в плюс что можно потом при необходимости распарсить клиентом
23 авг 15, 14:43    [18056618]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
sphinx_mv
Alexander Titkin
пропущено...


Что смущает в предложенном варианте с материализацией пути к элементу? Дети будут идти ровно за Родителем, как и желает ТС.
\1
\1\2
\1\2\6
\1\2\6\9
\1\2\7
\1\2\8
\1\3
\1\4

А кто-то даст свой любимый зуб, что парент ВСЕГДА будет иметь код меньше, чем у дитенка? :)
Достаточно рассмотреть двузначные ID, чтобы понять,
что предложенная запись с разделителем не будет работать при сортировке по ней.
23 авг 15, 16:00    [18056798]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
iap,
Лучше использовать STR(ID,10) вместо ID (если тип int).

примерчик можно?
23 авг 15, 16:30    [18056865]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
waszkiewicz,
ибо да
with cte(numb) as
(
select '1'
union
select '32'
union 
select '300'
union 
select '1000'
union 
select	'200'
union 
select '3'
)
select *
from cte
order by numb
23 авг 15, 16:33    [18056869]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
sphinx_mv
Сортировать строки из чисел с разделителями и надеяться на хоть какой-то порядок? Ну-ну... :)
Да, порядок будет такой, какой нужен ТС - что бы "запись с id=9 явилась сразу после своего родителя"
Что смущает?

Ну, если хочется, что бы и записи шли в порядке ИД, то можно дополнить номера нулями спереди (или пробелами - STR(ID,10) ). Хотя ТС такого не просил.

В любом случае, хоть порядок будет по ИД, хоть по строковым представлениям ИД - это обычно не тот порядок, который обычно нужен пользователю, так что неважно.
Пользователь же обычно хочет сортировки по именам, или проставленной вручную сортировки?
23 авг 15, 16:43    [18056896]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
waszkiewicz
так вроде?
Да.
waszkiewicz
iap,
Лучше использовать STR(ID,10) вместо ID (если тип int).

примерчик можно?
Да вот, в вашем коде, меняете convert(nvarchar(max),id) на STR(ID,10)
23 авг 15, 16:44    [18056898]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
alexeyvg
Да, порядок будет такой, какой нужен ТС - что бы "запись с id=9 явилась сразу после своего родителя"
Что смущает?
Например, что за 10 будет следовать 100, а не 11.
А некоторые цифры будут сравниваться с разделителем.
23 авг 15, 17:01    [18056943]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
## fa diezz ##
Guest
iap
Достаточно рассмотреть двузначные ID, чтобы понять,
что предложенная запись с разделителем не будет работать при сортировке по ней.


Почему-то не приходит в голову комбинация, когда работать не будет. Можно пример?
23 авг 15, 17:06    [18056961]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
[quot alexeyvg]
sphinx_mv
Пользователь же обычно хочет сортировки по именам, или проставленной вручную сортировки?

То-то и оно - точно в цель. Сатори по 1/2/3/4 уже наступило. На клиенте отсортирую элементы в пределах родительского узла. А вот чтоб сразу клиенту выгрузить отсортированное по "именам" в пределах узлов?
select c.* 
		,p.name
from cte c
join parts p
on c.ref=p.id
order by root

эта часть запроса джойнит имена.
Что-то еще может уточнить надо?
23 авг 15, 17:08    [18056964]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
iap
Например, что за 10 будет следовать 100, а не 11.
Дык пусть следуют, что такого?
Иерархия то правильно будет построена - то есть дети будут внутри веток родителей. Про сортировку по ИД, повторю, ТС не спрашивал.

Пользователю будет всё равно, за 10 будет следовать 100 или 11 - он же эти ИД не видит, он видит, например, имена, которые по любому будут отсортированы неправильно.

Для правильной соритровки по именам нужно вообще сортировать не по ИД, а по STR(row_number() over(order by name), 10)
Но ТС, повторю, про это не спрашивал.
23 авг 15, 17:09    [18056966]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
waszkiewicz
То-то и оно - точно в цель. Сатори по 1/2/3/4 уже наступило. На клиенте отсортирую элементы в пределах родительского узла. А вот чтоб сразу клиенту выгрузить отсортированное по "именам" в пределах узлов?

alexeyvg
Для правильной соритровки по именам нужно вообще сортировать не по ИД, а по STR(row_number() over(order by name), 10)
23 авг 15, 17:09    [18056968]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
## fa diezz ##,
1/200
10/1
10/1000
300/32
30000/2
32/2
23 авг 15, 17:10    [18056971]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
## fa diezz ##
Guest
waszkiewicz
## fa diezz ##,
1/200
10/1
10/1000
300/32
30000/2
32/2


и что? иерархия нарушена?
23 авг 15, 17:16    [18056991]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
## fa diezz ##
waszkiewicz
## fa diezz ##,
1/200
10/1
10/1000
300/32
30000/2
32/2


и что? иерархия нарушена?
Не, всё идеально. Не знаю, почему тут считают, что порядок
300/32
30000/2
32/2

неправильный. Всё по ТЗ "чтобы запись с id=9 явилась сразу после своего родителя" :-)
23 авг 15, 17:19    [18057001]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1087
[quot alexeyvg]
iap
Для правильной соритровки по именам нужно вообще сортировать не по ИД, а по STR(row_number() over(order by name), 10)
Но ТС, повторю, про это не спрашивал.

спрашиваю :)
CREATE TABLE [dbo].[Objects](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[parentid] [int] NULL,
	[ref] [int] NULL,
	[descr] [nvarchar](max) NULL,
 CONSTRAINT [PK_Plane] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Objects]  WITH CHECK ADD  CONSTRAINT [FK_Objects_Parts] FOREIGN KEY([ref])
REFERENCES [dbo].[Parts] ([id])
GO

ALTER TABLE [dbo].[Objects] CHECK CONSTRAINT [FK_Objects_Parts]


CREATE TABLE [dbo].[Parts](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [nvarchar](50) NOT NULL,
	[descr] [nvarchar](max) NULL,
	[parentid] [int] NULL,
	[messid] [int] NULL,
 CONSTRAINT [PK_Parts] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


мечтается заделать список из Parts.Name в соответствии с иерархией из Objects. Вот
23 авг 15, 17:21    [18057009]     Ответить | Цитировать Сообщить модератору
 Re: рекурсия/иерархия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
waszkiewicz
спрашиваю :)
Так я же уже написал - "сортировать не по ИД, а по STR(row_number() over(order by name), 10)"

Просто меняете в вашем коде ИД на вышеуказанное.
with cte as
(
select 
	o.id
	,o.ref
	,0 lvl
	,o.parentid
	,p.name
	,STR(row_number() over(order by p.name), 10) as root
from objects o
	join parts p
		on o.ref=p.id
where o.parentid is null
union all
select o.id
	,o.ref
	,c.lvl+1
	,o.parentid
	,p.name
	,convert(nvarchar(max),c.root) + STR(row_number() over(order by p.name), 10) as root
from objects o
	join cte c 
		on o.parentid=c.id
	join parts p
		on o.ref=p.id
)
select c.* 
from cte c
order by root
23 авг 15, 18:20    [18057168]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить