如何使用 Teradata SQL 对层次结构的所有子级/成员进行分组



我有一个表中许多不同的层次结构集的数据,例如子父关系,我需要对所有单独的层次结构进行分组。

例如:特定层次结构的所有成员都将在一个组中。

**Input**
party   related_party
1       2
1       3
3       4
3       5
5       6
6       7
7       8
7       16
8       9
9       11
9       12
**Output**
party   group
1       g1
2       g1
3       g1
4       g1  
5       g1
6       g1
7       g1
8       g1
9       g1
10      g1
11      g1
12      g1
16      g1

目前,我已经对同一表进行了 3 次左连接以跟踪数据直到 7 级。

sel columns
table a 
left join table b
on a.related_party=b.party
left join table c
on b.related_party=c.party;

需要跟踪直到层次结构的末尾。因此,如果有人有任何其他技术,请提出建议。

你没有层次结构,你有一个"有向图"。您可以尝试先删除直接链接,然后再遍历层次结构。但是你必须能够确定一个根。

为了防止循环,您需要创建一个显示您以前的参与方的路径。

-- remove duplicates: A-B & B-A
CREATE VOLATILE TABLE tab AS (
SELECT DISTINCT party , related_party
FROM tab_org t1
WHERE NOT EXISTS(
  SELECT * FROM tab_org t2
  WHERE t1.related_party = t2.party
    AND t1.party = t2.related_party
    AND t1.related_party < t2.related_party
)
AND related_party <> party
) WITH DATA
ON COMMIT PRESERVE ROWS
;
-- now use the cleaner data
WITH RECURSIVE cte 
AS
 (
   SELECT party, related_party, ROW_NUMBER() OVER (ORDER BY party) AS grp, CAST(TRIM(party) AS VARCHAR(10000)) AS PATH, 1 AS lvl
   FROM tab AS t
   WHERE NOT EXISTS
    (
      SELECT * FROM tab AS t2
      WHERE t.party = t2.related_party
    )
   UNION ALL
   SELECT tab.party,tab.related_party,  grp, 
      cte.PATH || '.' || TRIM(tab.party), cte.lvl + 1
   FROM cte JOIN tab
   ON tab.party = cte.related_party
         -- if new party is already in path it's a cycle
   WHERE '.'||cte.PATH||'.' NOT LIKE '%.'||TRIM(tab.party)||'.%'
     AND cte.lvl < 10  -- just in case, might be removed
 )
SELECT  * 
FROM cte
ORDER BY path

如果没有周期,这将起作用,否则会更复杂。根据您的实际数据,您可能需要最终DISTINCT

相关内容

  • 没有找到相关文章

最新更新