我在SQL Server 2014的表[AdjT]中存储了分层数据。数据的总深度是4级并且是固定的。
即,[父母 - 子女1 - 儿童2 - 儿童3]
列是:Adjt {Id,ParentId,Title,TypeM}
您可以在图像中看到数据。
多个层次结构(根据TypeM)存在于同一个表中(您可以看到2个父项)
我需要什么?
我需要为任何给定的Child获取所有父“Title”。例如,下面的图像显示Id的“层次结构”:TypeM:AAA
到目前为止我做了什么
此查询为我提供了子行及其直接父级。
select a.Title as P1, (select a1.Title from AdjT as a1 where a1.Id=a.ParentId) as P1 from Adjt as a where a.TypeM='AAA' and a.Id=4;
像这样:[无法绑定多部分标识符“a1.ParentId”。]
根据以下查询:
select
a.Title as P1
, (select a1.Title from AdjT as a1 where a1.Id=a.ParentId) as P2
, (select a2.Title from AdjT as a2 where a2.Id=a1.ParentId) as P3 --"a1.ParentId" ERROR
from
Adjt as a
where a.TypeM='AAA'
and a.Id=4;
即使我写为P2.ParentId,它也会给我:
无法绑定多部分标识符“P2.ParentId”。
我该怎么做才能让它发挥作用?
我目前使用的解决方法
我正在使用嵌套查询来获取我需要的数据和层次结构
使用以下查询完成:
select
a.Title as P1
, (select a1.Title from AdjT as a1 where a1.Id=a.ParentId) as P2
, (select a2.Title from AdjT as a2 where a2.Id=(select a1.ParentId from AdjT as a1 where a1.Id=a.ParentId)) as P3
, (select a3.Title from AdjT as a3 where a3.Id=(select a2.ParentId from AdjT as a2 where a2.Id=(select a1.ParentId from AdjT as a1 where a1.Id=a.ParentId))) as P4
from
Adjt as a
where a.TypeM='AAA'
and a.Id=4;
有没有更好的方法呢?为什么我只能访问第一列的parentId?
我无法编辑表的架构或数据的存储方式。必须使用叶节点的Id从下到上获取层次结构。如上所示。
我尝试使用CTE获取分层数据,但我希望它为“列”而不是“行”。将这些CTE行转换为“代码”中的列也不是一种选择。
如果任何人可以提出更好的方法来做到这一点,那将是最有帮助的。
感谢您阅读我的问题,我们将不胜感激。
答案 0 :(得分:2)
你想做一个像
这样的自我加入select
a.Title as P1
a1.Title as Tital1,
a2.Title as title2
from AdjT a
join AdjT a1 on a1.Id=a.ParentId
join AdjT a2 on a2.Id=a1.ParentId
where a.TypeM = 'AAA'
and a.Id = 4;
答案 1 :(得分:1)
实现这一目标需要几种技术。
首先是自我加入。实际上,自联接允许您将行转换为列。通过以此样式展平您的数据,您可以并排查看父级和子级。
接下来我们需要一个OUTER JOIN。因为您想从任何级别进行搜索,所以不会总是有3个父级(例如Id 2只有一个父级)。如果没有父项,则正常连接将过滤掉记录。当没有匹配的记录时,外连接通过返回NULL来避免这种情况。
我已在表VARIABLE中重新创建了您的示例数据。这样可以更轻松地共享示例代码。
样本数据
/* Table VAR creates sample records we can
* all share.
*/
DECLARE @Sample TABLE
(
Id INT PRIMARY KEY,
ParentId INT,
Title VARCHAR(50),
TypeM VARCHAR(3)
)
;
/* Populate sample data.
*/
INSERT INTO @Sample
(
Id,
ParentId,
Title,
TypeM
)
VALUES
(1, 0, 'Parent 1 - [P1]', 'AAA'),
(2, 1, 'Child 1 - [C1] P1', 'AAA'),
(3, 2, 'Child 2 - [C2] C1 P1', 'AAA'),
(4, 3, 'Child 3 - [C3] C2 C1 P1', 'AAA'),
(5, 0, 'Parent 1 - [P2]', 'DDD'),
(6, 5, 'Child 1 - [C1] P2', 'DDD'),
(7, 6, 'Child 2 - [C2] C1 P2', 'DDD'),
(8, 7, 'Child 3 - [C3] C2 C1 P2', 'DDD')
;
实施例
/* Self joins can extract the hierarchy.
* Outer joins ensure results are always returned.
*/
SELECT
s1.Title AS [P1],
s2.Title AS [P2],
s3.Title AS [P3],
s4.Title AS [P4]
FROM
@Sample AS s1
LEFT OUTER JOIN @Sample AS s2 ON s2.Id = s1.ParentId
LEFT OUTER JOIN @Sample AS s3 ON s3.Id = s2.ParentId
LEFT OUTER JOIN @Sample AS s4 ON s4.Id = s3.ParentId
WHERE
s1.Id = 4
;
尝试将WHERE id = 4替换为3以查看外部联接的实际效果。