Помогите оптимизировать

trayan

Пожалуйста, помогите оптимизировать код.Запрос такой: нужно вывести все задания сотрудника по определенному проекту. Условия: задания делятся на узловые (не привязанные к сотруднику и имеющие дочерние) и выполнимые (не имеющие дочерних заданий) Реализация://------------------------------------------------------------------------------declare @buff1 table(id_task int, id_parent_task int)declare @buff2 table(id_task int, id_parent_task int)declare @out table(id_task int)insert @buff1(id_task, id_parent_task) select id_task, id_parent_task from Tasks where id_task not in (select id_parent_task from Tasks where id_parent_task is not null) and id_employee = '{1*******-71E3-4406-BDEE-************}' --ид сотрудника and id_project = '1'--ид ************* @out(id_task) select id_task from @buff1----------------------------------declare @rows intset @rows = (select count(*) from @buff1)while (@rows>0)begin-------------------------------------------------------insert @buff2(id_task, id_parent_task) select id_task, id_parent_task from @buff1delete from @buff1insert @buff1(id_task, id_parent_task) select id_task, id_parent_task from Tasks where id_task in (select id_parent_task from @buff2 where id_parent_task is not null)delete from @buff2insert @out(id_task) select id_task from @buff1set @rows = (select count(*) from @buff1)end-------------------------------------------------------------------------------------------select distinct * from @out//----------------------------------------------------------------------------Нутром чую, что сделал все очень коряво))Приму любые предложения, советы, критику....P.S. сильно не ругайтесь. sql'ем занимаюсь третий день
12 ответов

trayan

Ну либо я туплю... либо этот код обрезан:
insert @buff1(id_task, id_parent_task)
select id_task, id_parent_task from Tasks
where id_task not in (select id_parent_task from Tasks where id_parent_task is not null)
and id_employee = '{1*******-71E3-4406-BDEE-************}' --ид сотрудника
and id_project = '1'--ид проекта


trayan

Ну я же сказал, что туплю))) Без выделения синтаксиса не увидел фрома)))P.S.Не могли бы вы точнее сказать по поводу задач... ну узловые/не узловые... какие считать - то надо?


trayan

Необходимо вывести все дерево заданий.Ну вроде:Project1:|-Task1|-Task2 (parent - 1)|-Task3 (parent - 2, employee - trayan)|-Task4|-Task5 (parent - 4, employee - trayan)|-Task6 (parent - 4, employee - trayan)Ссылки на эти таски (1-6) мне и нужно получить для вывода дерева заданий.


trayan

Не уверен, но мне кажется так:
SELECT t1.id_task
FROM Tasks t1
 INNER JOIN Tasks t2
 ON t1.id_task = t2.id_parent_task
WHERE t1.id_parent_task IS NOT NULL
 AND t1.id_employee = '{1*******-71E3-4406-BDEE-************}' --ид сотрудника
 AND t1.id_project = '1'--ид проекта


trayan

2 -=DiM@n=-Этот запрос выводит задания у которых есть и родительские и дочерние задания((


trayan

SELECT t1.id_task, 
 t1.id_parent_task, 
 CASE 
 WHEN t1.id_parent_task IS NULL THEN NULL ELSE t1.id_employee 
 END
FROM Tasks t1
 LEFT JOIN Tasks t2
 ON t1.id_task = t2.id_parent_task
WHERE t1.id_employee = '{1*******-71E3-4406-BDEE-************}'
 AND t1.id_project = '1'


trayan

2 -=DiM@n=-СПАСИБО!!!!все работает!P.S. еще бы разобраться как это работает))))


trayan

чет я рано обрадовался((запрос:
SELECT t1.id_task, 
 t1.id_parent_task, 
 CASE 
 WHEN t1.id_parent_task IS NULL THEN NULL ELSE t1.id_employee 
 END
FROM Tasks t1
 LEFT JOIN Tasks t2
 ON t1.id_task = t2.id_parent_task
WHERE t1.id_employee = '{1*******-71E3-4406-BDEE-************}'
 AND t1.id_project = '1'
выдает только одно задание с условием "id_parent_task IS NULL"переписал вот так:
SELECT distinct t1.id_task, 
 t1.id_parent_task
FROM Tasks t1
 LEFT JOIN Tasks t2
 ON t1.id_task = t2.id_parent_task or t2.id_task = t1.id_parent_task
WHERE t1.id_employee = '{1*******-71E3-4406-BDEE-************}'
 AND t1.id_project = '1'
вроде работает...только мне не нравится условие
t1.id_task = t2.id_parent_task or t2.id_task = t1.id_parent_task


trayan

заменить
set @rows = (select count(*) from @buff1)
на
set @rows = @@rowcount
и поставить после
insert @buff1


trayan

а вообще для 3-го дня неплохо :-)


trayan

Добиваю первый вариант:
declare @Result table(id_task int, id_parent_task int, [level] int)
declare @CurLevel int

insert @Result(id_task, id_parent_task, level)
	select id_task, id_parent_task, <b>0</b> --level
	from Tasks
	where id_employee = (select UserId from aspnet_Users where UserName ='trayan')
	 and id_project = '1'
set @CurLevel = <b>1</b>;

while ((select count(*) FROM @Result where level = @CurLevel-<b>1</b>)><b>0</b>)
begin-------------------------------------------------------
insert @Result(id_task, id_parent_task, level)
	select 
	 Result.id_parent_task as id_task
	, (select id_parent_task from Tasks where Tasks.id_task = Result.id_parent_task) as id_parent_task
	, @CurLevel
	FROM @Result as Result
	where Result.level = @CurLevel-<b>1</b> 
	 And not Result.id_parent_task is null	

set @CurLevel = @CurLevel + <b>1</b> 

end---------------------------------------------------------

select distinct id_task from @Result


trayan

а запрос:
SELECT distinct t1.id_task, 
 t1.id_parent_task
FROM Tasks t1
 LEFT JOIN Tasks t2
 ON t1.id_task = t2.id_parent_task or t2.id_task = t1.id_parent_task
WHERE t1.id_employee = '{1*******-71E3-4406-BDEE-************}'
 AND t1.id_project = '1'
не всегда работает((