【问题标题】:Family parent child relation家庭亲子关系
【发布时间】:2021-11-29 07:34:28
【问题描述】:

enter image description here

我需要在下图中显示以下层次结构

我用 cte 编写了以下代码: --===========================

;With Hierarchy (Name,Path)
AS
(
SELECT t.FamilyName, CAST(t.FamilyName AS varchar(max))
FROM tblFamily t
LEFT JOIN tblFamily t1
ON t1.FamilyID = t.ParentFamilyId
WHERE t1.FamilyID IS NULL
UNION ALL
SELECT t.FamilyName, CAST('All Categories'+'>'++h.FamilyName + '->' + t.FamilyName AS varchar(max))
FROM tblFamily h
INNER JOIN tblFamily t
ON t.FamilyID = h.ParentFamilyId
)



SELECT Name,Path
FROM Hierarchy
OPTION (MAXRECURSION 0)

我已经硬编码了所有类别,它是所有孩子的父母,但我也需要这个自然的如何做到这一点? 这是表格: enter image description here

【问题讨论】:

  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或键入问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • 除此之外......正如有些人喜欢在这里说的:; 是语句终止符,而不是语句开始符。您应该使用 ; 字符来终止所有 SQL 语句,而不仅仅是在可能产生错误的语句前面加上一个,例如 WITH
  • 首先使用一个层次结构,你需要一个锚。哪个是主表,而主表只在它的NULL条件下。以下答案有助于结构和解释:stackoverflow.com/questions/47660012/t-sql-hierarchy-query

标签: sql sql-server tsql


【解决方案1】:

您在错误的方向创建树。在这种情况下,从树的顶部开始向下工作要容易得多。

WITH Hierarchy
AS
(
    SELECT t.FamilyID, t.FamilyName, FamilyPath = CAST(t.FamilyName AS varchar(max))
    FROM tblFamily t
    WHERE t.ParentFamilyId IS NULL

    UNION ALL

    SELECT t.FamilyID, t.FamilyName, h.FamilyPath + ' > ' + t.FamilyName
    FROM tblFamily t
    INNER JOIN Hierarchy h ON h.FamilyID = t.ParentFamilyId
)
SELECT
  FamilyID,
  FamilyName,
  FamilyPath
FROM Hierarchy;

请注意,使用MAXRECURSION 0 通常不是一个好主意,因为大多数树不会走那么远,如果层次结构中有循环,这可能会导致无限递归。

【讨论】:

  • 您好,Union All 后使用 Hierarchy 表加入时,没有 FamilyID 列。它产生错误
  • 只要添加到CTE,如图
  • 赋值(第一张图)明确表示要使用 OUTER JOIN 来使用对同一个表的三个引用进行自连接,甚至指定要使用哪些表别名。递归 CTE 是我要走的路,但它没有回答 OP 想要回答的问题。
  • 我注意到它作为作业图像的一部分出现在文本中。它真的应该在帖子的问题文本中。 OP自己使用了CTE。如果您觉得这需要一个不同的答案,欢迎您自己提供
【解决方案2】:

您的分配告诉您使用外部联接将三个引用链接到同一个表,甚至告诉您为表起别名。与 CTE 或递归无关。

SELECT
  Family.*,
  COALESCE(TopFamily.FamilyName + ' > ', '')
  + COALESCE(ParentFamily.FamilyName + ' > ', '')
  + Family.FamilyName
    AS FamilyPath
FROM
  tblFamily   AS Famiky
LEFT JOIN
  tblFamily   AS ParentFamily
    ON ParentFamily.FamilyID = Family.ParentFamilyID
LEFT JOIN
  tblFamily   AS TopFamily
    ON TopFamily.FamilyID = ParentFamily.ParentFamilyID

第一个引用获取所有系列条目,无论层次结构中的级别如何。

左连接获取父节点,如果有的话,如果没有,则为 NULL。第二个左连接再次执行相同的操作,本质上是获取祖父母(如果有的话)。

这意味着它只适用于设定的深度,但这就是你的任务所要求的。

SELECT 子句将每个级别的FamilyName 包装在COALESCE() 中,这样> 仅在不是NULL 时添加到名称中,并将任何NULL 替换为空字符串(将NULL 加入另一个字符串只会给出NULL)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    相关资源
    最近更新 更多