I have 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 |
-----|------------|------------|
EDIT: here is a representation of the tree:
_______root_______
/ | \
JAMES ISAC LUX
| / \ |
LISA TWITCH LISA LISA
| | |
Andrew EZREAL EZREAL
and my second table is like the following:
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 |
------|-------|-------|--------|-------------|
My need is to figure out a way (function or procedure) that starts from table 2 (t_Path) and find each leaf (value of grandgrandSon if not null otherwise grandson if not null etc...) id in t_searchCriteria table:
Since we can have the same value of node in the t_search criteria table then the unicity of a node is its value and its parent value and its grandParentValue (and we have another rule; a parent can't have 2 children with same name)
I have tried to make a function but I didn't find a way to do a function inside another function besides working with objects like in c# or another programming language.
I need to make a function that takes an int ID which is the ID of a path from table t_Path and figure out the leaf of the path (this is done), the problem here is how to get the id of that leaf from t_searchCriteria table since we can have multiple criteria with same value (name) even with same parent name, the grandParent Value will make difference.
for example of execution:
Select FunctionGetCriteriaId(6)
will return 15
where 6 is the id of the path : 6 |root |LUX | LISA | EZREAL |
and 15 is the id of the criteria : 15 | EZREAL | 14 |
Can anyone help me to figure this out please?
EDIT: to be more specific the function takes the id of the path in table 2, for example 5 ( 5 |root |LUX | LISA | NULL |) and returns the id of "LISA" (the leaf not the others ;) ) in table 1 that is 14. (of course taking note of the rules set before.)
EDIT 2: updated unicity condition in the tree
You can do this easily using LEFT JOINS
and MAX
and COALESCE
. This is full working example. You can play with it:
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;