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

Откуда:
Сообщений: 566
Добрый день!
Имеется таблица Test с полями ID (номер задачи),Task (наименование задачи)

CREATE TABLE dbo.TEST([ID] INTEGER, [Task] NVARCHAR(100))
GO
INSERT dbo.TEST VALUES('1', N'Задача 1')
INSERT dbo.TEST VALUES('1.1', N'Подзадача 1')
INSERT dbo.TEST VALUES('2', N'Задача 2')
INSERT dbo.TEST VALUES('2.1', N'Подзадача 1')
INSERT dbo.TEST VALUES('2.2', N'Подзадача 2')
INSERT dbo.TEST VALUES('2.2.1', N'Подзадача 1')
GO

Необходимо написать запрос с выводом данных ID, строка с именами задач верхнего уровня через разделитель '->'+Task:
'1','Задача 1',''
'1.1','Задача 1->Подзадача 1'
'2','Задача 2',''
'2.1','Задача 2->Подзадача 1'
'2.2','Задача 2->Подзадача 2'
'2.2.1','Задача 2->Подзадача 2->Подзадача 1' и т.д.
Вложенность неопределенна.
Подскажите как сделать.....
Спасибо.
28 май 14, 17:34    [16087106]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Glory
Member

Откуда:
Сообщений: 104751
А как вы умудрились в INTEGER занести значения 1.1 и 2.2.1 ?
28 май 14, 17:43    [16087180]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Lexx_SQL, почему у вас id типа integer, когда заполняете строкой?

а по вашему вопросу - берете эту строку, которую пытаетесь запихнуть в поле id, и при помощи replace заменяете каждую точку на слово " -> подзадача "
28 май 14, 17:44    [16087190]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Lexx_SQL
Member

Откуда:
Сообщений: 566
Shakill,
ID -NVARCHAR...

"берете эту строку, которую пытаетесь запихнуть в поле id, и при помощи replace заменяете каждую точку на слово " -> подзадача " "
'Задача' , 'Подзадача'- это условное наименование, и его значение мы можем взять по номеру ID уровня выше.
Есть примеры по составлению строки:
select [ID],
  [Name] = replace((select [Name] as 'data()' from TEST where [Тип] = t.[Тип] for xml path('')), ' ', '->')
from dbo.TEST t
group by [ID]

Но запрос собирает данные только по совпадающим ID, а у меня иерархия.
29 май 14, 09:53    [16089239]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
Lexx_SQL,

рекурсивное CTE
29 май 14, 09:55    [16089252]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
китайский сервер
Member [скрыт] [заблокирован]

Откуда:
Сообщений: 3582
Lexx_SQL,

;with 
a as (select ID, cast([Task] as nvarchar(max)) as [Task], len([ID])-len(replace(ID,'.',''))+1 as [level] from dbo.TEST),
b as (
	select ID, [Task], [level] from a where [level]=1

	union all

	select a.ID, b.[Task]+'->'+a.[Task], a.[level] from a inner join b on a.[level]-1=b.[level] and a.ID like b.ID+'.%'
)

select * from b
29 май 14, 10:06    [16089298]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Glory
Member

Откуда:
Сообщений: 104751
select *, replace((select [Task] as 'data()' from @TEST b where a.[ID] LIKE b.[ID]+'%' for xml path('')), ' ', '->')
from @TEST a
29 май 14, 10:22    [16089387]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Lexx_SQL
Member

Откуда:
Сообщений: 566
Glory,

Спасибо огромное. То что надо!!!
29 май 14, 10:28    [16089431]     Ответить | Цитировать Сообщить модератору
 Re: Запрос-> Собрать наименования подзадач  [new]
Glory
Member

Откуда:
Сообщений: 104751
select *, replace((select [Task] as 'data()' from @TEST b where a.[ID] LIKE b.[ID]+'.%' for xml path('')), ' ', '->')
from @TEST a

Так правильнее. Ибо нумерация может быть и многозначной
29 май 14, 10:49    [16089582]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить