TSQL(我在Dynamics 365中使用它)
我有两个select
查询。他们都使用递归:
-- 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;
另外,两个查询均有效。但是我需要将其结果合并为一个。我该怎么办?
这是我的尝试,但是不起作用:
-- 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
我得到了错误:
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.
已更新:
谢谢大家!
有效:
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;
但是第二个选择包含的记录与我期望的记录不同,因为我评论了order by
。我该如何解决?
UPDATED2:
我尝试解决oredr by
问题:
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
答案 0 :(得分:3)
您正在尝试在现有语句中开始第二个WITH
,这不是CTE的工作方式。您只需声明一次WITH
:
WITH tree ([Name], Id, ParentId, pathstr, targetId, targetName) as (
SELECT [Name],
BusinessUnitId,
ParentBusinessUnitId,
[Name], --Name again?
BusinessUnitId AS targetId,
[Name] --Name again again?
FROM BusinessUnit WITH (NOLOCK) --Why 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) --T for Business name, not for Tree?
INNER JOIN tree ON T.ParentBusinessUnitId = tree.Id),
tree2 (Name, Id, ParentId, pathstr, targetId, targetName) AS(
SELECT [Name],
BusinessUnitId,
ParentBusinessUnitId,
[Name], --Name again?
BusinessUnitId AS targetId,
[Name] --Name again again?
FROM BusinessUnit WITH (NOLOCK) --Why NOLOCK?
WHERE BusinessUnitId = 'D60D6FCF-FC0E-E311-BA46-00505692007C'
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) --T for Business name, not for Tree?
INNER JOIN tree ON T.ParentBusinessUnitId = tree.Id)
SELECT Id, pathstr
FROM tree WITH (NOLOCK)
UNION ALL
SELECT Id, pathstr
FROM(SELECT TOP(1) Id, pathstr
FROM tree2 WITH (NOLOCK)
ORDER BY LEN(pathstr) DESC);
我这里还没有解决其他错误,例如Name
在您的CTE中被声明了3次)
编辑:在SQL中添加了一些注释。
答案 1 :(得分:1)
在主查询中使用的ORDER BY
子句可能很棘手,因为UNION
不允许您想到的所有可能性。您的联合查询应如下所示:
with
tree (...) as (
...
),
tree2 (...) as (
...
)
select Id, pathstr
from tree
union ( -- parenthesis needed because of the inner ORDER BY
select top(1) Id, pathstr
from tree2 order by len(pathstr) desc
)
order by pathstr -- you do want to order by pathstr, right?