如何运行Teradata递归查询以查找表中的层次结构?

时间:2017-06-02 11:11:11

标签: sql teradata recursive-query

我有一张桌子 -

ID       Name
A        Steve
AA       Carla
AAA      Anthony
AAAA     Martin
AAB      Casey
AABA     Mark

上面的输入数据

•员工“Steve”的ID为“A”。像这样的单个字符表示客户在没有任何推荐的情况下购买了产品。

•从史蒂夫的转介中,卡拉购买了另一种产品并获得了“AA”的身份证。 Carla的客户代码“AA”表示他被ID为“A”的某个客户推荐。

•根据Carla的推荐,Anthony和Casey分别购买了产品并获得了“AAA”和“AAB”的ID,表示他们被Carla推荐,ID为“AA”。

•每个推介的ID都有一个模式,可以在链中一直翻译成ID。

我需要使用Teradata SQL递归查询将此表转换为下表

DATA LINEAGE
1>Steve
1.1>>Carla
1.1.1>>>Anthony
1.1.1.1>>>>Martin
1.1.2>>>Casey
1.1.2.1>>>>Marc

以下几点值得一提:

•特定人员的多个推荐按字母顺序排列。例如,安东尼&凯西以字母升序显示,安东尼获得前缀1.1.1而凯西获得1.1.2。

•可能有多个客户启动了链,即没有任何推荐的直接客户。

•所有直接客户的输出开头都应该有整数(没有点和单箭头)。

•启动链的客户,即直接客户,也应按字母顺序排列。

•前缀符号数“>”对应于层次结构的深度。

1 个答案:

答案 0 :(得分:1)

这不是递归的,但我觉得它不需要。

CREATE MULTISET VOLATILE TABLE voltest
(
    id VARCHAR(50),
    nm VARCHAR(50)
) PRIMARY INDEX (id) ON COMMIT PREServe ROWS;
INSERT INTO voltest(id,nm) VALUES ('A','Steve');
INSERT INTO voltest(id,nm) VALUES ('AA','Carla');
INSERT INTO voltest(id,nm) VALUES ('AAA','Anthony');
INSERT INTO voltest(id,nm) VALUES ('AAAA','Martin');
INSERT INTO voltest(id,nm) VALUES ('AAB','Casey');
INSERT INTO voltest(id,nm) VALUES ('AABA','Mark');

SELECT
    path || bumpers || nm as "DATA LINEAGE"
FROM
(
    SELECT
        oreplace(TRIM(TRAILING '.' FROM (XMLAGG(trim(id_number) || '.' ORDER BY token_index) (VARCHAR(50)))), ' ', '') as path,
        bumpers,
        nm
    FROM
        (
            SELECT to_number(token, 'xxxxx')-9 as id_number, nm, token, token_index, SUBSTRING('>>>>>>>>>>>>>>' FROM 1 FOR max(token_index) OVER (PARTITION BY nm)) as bumpers
            FROM TABLE (
                REGEXP_SPLIT_TO_TABLE(voltest.nm, volTest.id, '', 'i')
                    RETURNS (nm VARCHAR(50) character set unicode, token_index integer, token varchar(50) CHARACTER SET UNICODE)
                ) AS dt
        ) sub
    GROUP BY nm, bumpers
) sub2

regexp_split_to_table会将id列中的每个字符拆分为自己的行,并以nm为键。我们还在token_index中捕获了该位置。拆分字符在token中捕获。

我们使用to_number吐出token的十六进制表示的整数值,然后减去9.所以A = 1,B = 2,等等上。

我们在MAX()上为每个名称使用窗口函数token_index,以确定为该名称提取多少箭头>

然后我们将所有这些拼接在一起,XMLAGG将句点字符串与句点分隔符聚合在一起(修剪最后一个)。

这将吐出以下内容:

+-------------------+
|   DATA LINEAGE    |
+-------------------+
| 1.1.1.1>>>>Martin |
| 1.1.1>>>Anthony   |
| 1.1.2.1>>>>Mark   |
| 1.1>>Carla        |
| 1>Steve           |
| 1.1.2>>>Casey     |
+-------------------+