sql - 将递归 CTE 与另一个查询相结合
问题描述
我有一个位置表,每个位置都可以有一个父位置
LocationId | ParentLocationId
-----------------------------
1 null
2 1
3 2
4 2
我设法创建了一个递归 CTE,它为我提供了任何给定位置 id 的父位置 id(加上原始位置 id)
WITH GetLocationParents AS
(
select [LocationId], [ParentLocationId] from Locations
where LocationId = 3
UNION ALL
select i.[LocationId], i.[ParentLocationId]
from Locations i
join GetLocationParents cte on cte.ParentLocationId = i.LocationId
)
SELECT [ParentLocationId] FROM GetLocationParents
WHERE [ParentLocationId] is not NULL;
例如where LocationId = 3
将返回:
ParentLocationId
----------------
3
2
1
在另一个表中,我有一个查询,它将LocationId
作为字段之一返回:
select exi.PersonId, exi.LocationId from Persons e
left join PersonHasLocations exi on e.PersonId = exi.PersonId
left join Locations i on exi.LocationId = i.LocationId
带有 where 子句的哪个会返回如下内容:
PersonId | LocationId
---------------------
100 3
我正在尝试组合这些查询以获得结果:
PersonId | LocationId
---------------------
100 3
100 2
100 1
我正在尝试以下方法,但它仍然只返回第一行:
WITH
GetLocationParents AS
(select [LocationId], [ParentLocationId] from Locations
--where LocationId = 3
UNION ALL
select i.[LocationId], i.[ParentLocationId]
from Locations i inner join GetLocationParents cte
on cte.ParentLocationId = i.LocationId),
GetPersons AS
(select exi.PersonId, exi.LocationID from Persons e
left join PersonHasLocations exi on e.PersonID = exi.PersonId
left join Locations i on exi.LocationId = i.LocationID)
SELECT * FROM GetLocationParents gip
INNER JOIN GetPersons ge on ge.LocationId = gip.LocationID
WHERE ge.PersonId = 100
是否可以将递归查询与这样的普通查询合并?
解决方案
我猜你的 cte 中有一个小错误。我建议将查询更改如下:
DECLARE @t TABLE (
LocationId int,
ParentLocationId int
)
INSERT INTO @t VALUES
(1, NULL)
,(2, 1)
,(3, 2)
,(4, 2)
;WITH GetLocationParents AS
(
select [LocationId] AS k, [LocationId], [ParentLocationId] from @t
UNION ALL
select k, i.[LocationId], i.[ParentLocationId]
from GetLocationParents cte
join @t i on cte.ParentLocationId = i.LocationId
)
SELECT *
FROM GetLocationParents
WHERE k = 3
有了这个,您会收到一个列表,其中包含您在第一列中过滤的值,以及在第二列中高于此的所有依赖“级别”。然后可以使用它来加入您的第二个表。
请记住 - 根据您的关卡数量 - 您将不得不照顾MAX RECUSRSION
。
推荐阅读
- python - 使用键将列表转换为字典列表
- r - 处理 JSON 文件并将其下载到特定文件夹中
- java - 为什么 repaint() 不在摆动计时器中调用paintcomponent?
- python - Selenium + Python 数据抓取不起作用。Shopee 的产品名称未保存在 csv 文件中
- next.js - 我看不到 Next.js 默认页面
- r - 替换矩阵中的重复项
- reactjs - 如何在 react-native-gifted-chat 中左右显示聊天消息
- go - 有没有办法将 json 查询转换为人类可用的 Kibana 链接?
- javascript - 如何根据键对对象数组进行排序并设置一个在顺序更改时应递增的附加键?
- java - 类型擦除后的类型安全?