TSQL (I use it in Dynamics 365)
I have two select
queries. They both use recursion:
-- first selection
with tree (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = '9A8E9F45-0C5C-E911-811E-00505682357C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((tree.pathstr + '/' + T.Name) as nvarchar(160)) as pathstr,
tree.targetId, tree.targetName
from BusinessUnit as T with (nolock)
inner join tree on T.ParentBusinessUnitId = tree.Id)
select Id, pathstr
from tree with (nolock) order by pathstr;
-- second selection
with tree2 (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = 'D60D6FCF-FC0E-E311-BA46-00505692007C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((T.Name + '/' + tree2.pathstr) as nvarchar(160)),
tree2.targetId, tree2.targetName
from BusinessUnit as T with (nolock)
inner join tree2 on tree2.ParentId = T.BusinessUnitId)
select top(1) Id, pathstr
from tree2 with (nolock) order by len(pathstr) desc;
Separately, both queries work. But I need to union their results into one. How can I do it?
This is my attemption to do it, but it doesn't work:
-- first selection
with tree (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = '9A8E9F45-0C5C-E911-811E-00505682357C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((tree.pathstr + '/' + T.Name) as nvarchar(160)) as pathstr,
tree.targetId, tree.targetName
from BusinessUnit as T with (nolock)
inner join tree on T.ParentBusinessUnitId = tree.Id)
select Id, pathstr
from tree with (nolock) order by pathstr
union all
-- second selection
with tree2 (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = 'D60D6FCF-FC0E-E311-BA46-00505692007C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((T.Name + '/' + tree2.pathstr) as nvarchar(160)),
tree2.targetId, tree2.targetName
from BusinessUnit as T with (nolock)
inner join tree2 on tree2.ParentId = T.BusinessUnitId)
select top(1) Id, pathstr
from tree2 with (nolock) order by len(pathstr) desc
I get the error:
Msg 156, Level 15, State 1, Line 13
Incorrect syntax near the keyword 'union'.
Msg 319, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
UPDATED:
Thank you all!
It works:
with tree (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = '9A8E9F45-0C5C-E911-811E-00505682357C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((tree.pathstr + '/' + T.Name) as nvarchar(160)) as pathstr,
tree.targetId, tree.targetName
from BusinessUnit as T with (nolock)
inner join tree on T.ParentBusinessUnitId = tree.Id),
tree2 (Name2, Id2, ParentId2, pathstr2, targetId2, targetName2)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = 'D60D6FCF-FC0E-E311-BA46-00505692007C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((T.Name + '/' + tree2.pathstr2) as nvarchar(160)),
tree2.targetId2, tree2.targetName2
from BusinessUnit as T with (nolock)
inner join tree2 on tree2.ParentId2 = T.BusinessUnitId)
select Id, pathstr
from tree with (nolock) --order by pathstr
UNION ALL
select top(1) tree2.Id2, tree2.pathstr2
from tree2 with (nolock) --order by len(tree2.pathstr2) desc;
But second selection contains not the same records I expected because I commented order by
. How can I fix it?
UPDATED2:
I try to solve the oredr by
problem:
with tree (Name, Id, ParentId, pathstr, targetId, targetName)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId as targetId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = '9A8E9F45-0C5C-E911-811E-00505682357C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((tree.pathstr + '/' + T.Name) as nvarchar(160)) as pathstr,
tree.targetId, tree.targetName
from BusinessUnit as T with (nolock)
inner join tree on T.ParentBusinessUnitId = tree.Id),
tree2 (Name2, Id2, ParentId2, pathstr2, targetId2, targetName2)
as (select Name, BusinessUnitId, ParentBusinessUnitId, Name, BusinessUnitId, Name
from BusinessUnit with (nolock)
where BusinessUnitId = 'D60D6FCF-FC0E-E311-BA46-00505692007C'
union all
select T.Name, T.BusinessUnitId, T.ParentBusinessUnitId, cast((T.Name + '/' + tree2.pathstr2) as nvarchar(160)),
tree2.targetId2, tree2.targetName2
from BusinessUnit as T with (nolock)
inner join tree2 on tree2.ParentId2 = T.BusinessUnitId)
select Id, pathstr
from tree with (nolock)
UNION ALL
-- subquery:
(select top(1) tree2.Id2, tree2.pathstr2
from tree2 with (nolock) order by len(pathstr2) desc) -- Error: Incorrect syntax near the keyword 'order'.
order by pathstr