级联函数 SQL 从树结构到平面数据结构

Cascade funtions SQL to go from tree structure to flat data structure

我有 2 tables :

table1 t_SearchCriteria:

------------------------------
ID   |  VALUE     | IDParent   |
-----|------------|------------|
 0   |   root     |     -1     |
-----|------------|------------|
 1   | JAMES      |      0     |
-----|------------|------------|
 2   | ISAC       |      0     |
-----|------------|------------|
 3   | LISA       |      1     |
-----|------------|------------|
 4   | Andrew     |      3     |
-----|------------|------------|
 5   | LISA       |      2     |
-----|------------|------------|
 6   | EZREAL     |      5     |
-----|------------|------------|
 10  | twitch     |      2     |
-----|------------|------------|
 13  | LUX        |      0     |
-----|------------|------------|
 14  | LISA       |      13    |
-----|------------|------------|
 15  | EZREAL     |      14    |
-----|------------|------------|

编辑:这是树的表示:

                                            _______root_______
                                           /        |         \
                                       JAMES       ISAC       LUX
                                         |        /   \         |
                                        LISA   TWITCH  LISA    LISA
                                         |              |       |
                                       Andrew        EZREAL   EZREAL

我的第二个 table 如下所示:

table t_Path

idPath|Person1|  Son  |grandSon|grandgrandSon|
------|-------|-------|--------|-------------|
   1  |root   |JAMES  | LISA   |ANDREW       |
------|-------|-------|--------|-------------|
   2  |root   |ISAC   | LISA   |EZREAL       |
------|-------|-------|--------|-------------|
   3  |root   |ISAC   | NULL   |TWITCH       |
------|-------|-------|--------|-------------|
   4  |root   |LUX    | NULL   |  NULL       |
------|-------|-------|--------|-------------|
   5  |root   |LUX    | LISA   |  NULL       |
------|-------|-------|--------|-------------|
   6  |root   |LUX    | LISA   | EZREAL      |
------|-------|-------|--------|-------------|

我需要找出一种方法(函数或过程)从 table 2 (t_Path) 开始并找到每片叶子(grandgrandSon 的值如果不为 null 否则 grandson 如果不为 null等等...) t_searchCriteria table:

中的 ID

因为我们可以在 t_search 条件 table 中有相同的节点值,所以节点的唯一性是它的值和它的 parent 值和它的 grandParentValue (我们还有一条规则;一个 parent 不能有 2 个同名的孩子)

我尝试创建一个函数,但除了像在 c# 或其他编程语言中那样使用 objects 之外,我没有找到在另一个函数中执行函数的方法。

我需要制作一个函数,它接受一个 int ID,它是来自 table t_Path 的路径的 ID,并找出路径的叶子(已完成),问题这里是如何从 t_searchCriteria table 获取那片叶子的 ID 因为我们可以有多个具有相同值(名称)的标准,即使具有相同的 parent 名称,grandParent 值也会有所不同。

执行示例: Select FunctionGetCriteriaId(6) 将 return 15

其中 6 是路径的 ID:6 |root |LUX | LISA | EZREAL |

15 是标准的 id:15 | EZREAL | 14 |

谁能帮我解决这个问题?

编辑:更具体地说,函数采用 table2 中路径的 ID,例如 5(5 |root |LUX | LISA | NULL |)和 returns "LISA" 的 ID(叶子不是其他 ;))在 table 1 中是 14。(当然要注意之前设置的规则。)

编辑 2: 更新了树中的唯一性条件

您可以使用 LEFT JOINSMAX 以及 COALESCE 轻松完成此操作。这是完整的工作示例。你可以玩它:

DECLARE @t_SearchCriteria TABLE
(
    [ID] SMALLINT
   ,[Value] VARCHAR(12)
   ,[IDParent] SMALLINT
);

INSERT INTO @t_SearchCriteria ([ID], [Value], [IDParent])
VALUES (0, 'root', -1)
      ,(1, 'JAMES', 0)
      ,(2, 'ISAC', 0)
      ,(3, 'LISA', 1)
      ,(4, 'Andrew', 3)
      ,(5, 'LISA', 2)
      ,(6, 'EZREAL', 5)
      ,(10, 'twitch', 2)
      ,(13, 'LUX',  0)
      ,(14, 'LISA', 13)
      ,(15, 'EZREAL', 14);

DECLARE @t_Path TABLE
(
    [idPath] SMALLINT
   ,[Person1] VARCHAR(12)
   ,[Son] VARCHAR(12)
   ,[grandSon] VARCHAR(12)
   ,[grandgrandSon] VARCHAR(12)
);

INSERT INTO @t_Path ([idPath], [Person1], [Son], [grandSon], [grandgrandSon])
VALUES (1, 'root', 'JAMES', 'LISA', 'ANDREW')
      ,(2, 'root', 'ISAC', 'LISA', 'EZREAL')
      ,(3, 'root', 'ISAC',  'TWITCH', NULL)
      ,(4, 'root', 'LUX', NULL, NULL)
      ,(5, 'root', 'LUX', 'LISA', NULL)
      ,(6, 'root', 'LUX', 'LISA', 'EZREAL');


-- the function input parameter
DECLARE @idPath SMALLINT = 5;

-- the function body

DECLARE @Person1 VARCHAR(12)
       ,@Son VARCHAR(12)
       ,@grandSon VARCHAR(12)
       ,@grandgrandSon VARCHAR(12);

SELECT @Person1 = [Person1]
      ,@Son = [Son]
      ,@grandSon = [grandSon]
      ,@grandgrandSon = [grandgrandSon]
FROM @t_Path P
WHERE P.[idPath] = @idPath;

SELECT COALESCE(MAX(S5.[ID]), MAX(S4.[ID]), MAX(S3.[ID]), MAX(S2.[ID]), MAX(S1.[ID]))
FROM @t_SearchCriteria S1
LEFT JOIN @t_SearchCriteria S2
    ON S1.[ID] = S2.[IDParent]
    AND S1.[Value] = @Person1
LEFT JOIN @t_SearchCriteria S3
    ON S2.[ID] = S3.[IDParent]
    AND S2.[Value] = @Son
    AND @Person1 IS NOT NULL
LEFT JOIN @t_SearchCriteria S4
    ON S3.[ID] = S4.[IDParent]  
    AND S3.[Value] = @grandSon
    AND @grandgrandSon IS NOT NULL
LEFT JOIN @t_SearchCriteria S5
    ON S4.[ID] = S5.[IDParent]
    AND S4.[Value] = @grandgrandSon
WHERE S1.[Value] = @Person1;