我有两张桌子:
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
我的第二张表如下:
表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 |
------|-------|-------|--------|-------------|
我需要找出一种从表2(t_Path)开始的方法(函数或过程),并在t_searchCriteria表中找到每个叶子(grandgrandSon的值,如果不是null,否则孙子,如果不是null等...)id:
由于我们可以在t_search条件表中具有相同的节点值,因此节点的唯一性是其值及其父值及其grandParentValue(我们有另一个规则;父节点不能有2个子节点同名)
我试图创建一个函数,但除了使用c#或其他编程语言之类的对象之外,我还没有找到在另一个函数中执行函数的方法。
我需要创建一个函数,它接受一个int ID,它是来自表t_Path的路径的ID,并找出路径的叶子(这已经完成),这里的问题是如何获取该叶子的id从t_searchCriteria表开始,因为即使具有相同的父名,我们也可以有多个具有相同值(名称)的标准,grandParent值将有所不同。
例如执行:
Select FunctionGetCriteriaId(6)
将返回15
其中6是路径的ID:6 |root |LUX | LISA | EZREAL |
和15是标准的ID:15 | EZREAL | 14 |
有人可以帮我解决这个问题吗?
编辑:更具体地说,fucntion采用表2中路径的id,例如5(5 | root | LUX | LISA | NULL |)并返回" LISA"的id。 (叶子不是其他人;))在表1中是14(当然注意到之前设定的规则。)
编辑2: 在树中更新了unicity条件
答案 0 :(得分:0)
您可以使用LEFT JOINS
和MAX
以及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;