sql - TSQL:如何合并多个复杂的选择?
问题描述
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
。我该如何解决?
更新2:
我尝试解决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
解决方案
您试图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 中添加了一些注释。
推荐阅读
- javascript - 如何停止 Angular 7 中某个特定语句的死代码消除
- tsql - 在不使用“GO”(对于存储过程)执行时如何使查询按“顺序”运行?
- python - AllenNLP 在“成为”句子上失败。途中发生了一些事情
- kubernetes - 我正在使用 Helm 从 Bitnami 安装自定义 WordPress 图像。无法从 Docker Hub 中的私有存储库中提取图像
- geometry - 将过渡 + 圆 + 过渡曲线拟合到一组测量点
- python - Pygame - 敌人射击,团体问题
- r - Shiny 在 R 中没有给我正确的直方图
- php - 在 PHP 中根据 XSD 1.1 模式验证 XML
- php - 数据透视表 Laravel 中的外键问题
- c# - .net 中的堆栈操作