I am trying to find all first items of the last hierarchy members ("leafs") in a SQL Server hierarchy. I was able to find similar questions, however solutions with GetAncestors
don't work with our SQL Server version.
I was able to use this solution:
SELECT
*,
CONVERT(nvarchar(20), MasterOrder) AS HierarchyString
FROM
TestTable2 PARENT
WHERE
NOT EXISTS (SELECT *
FROM TestTable2 CHILD
WHERE CHILD.Id <> PARENT.Id
AND CHILD.MasterOrder.IsDescendantOf(PARENT.MasterOrder) = 1)
This returns the correct results, but for some reason only 12 out of 25 rows. I think too many rows are included in the NOT EXISTS
range, but I don't have experience with CHILD
and PARENT
keywords and interestingly enough, failed to find MS documentation for them.
EDIT: I couldn't find it, because I was very tired and somehow didn't noticed those are aliases, not keywords :-)
Here is data with marked rows (<<<
), that the query should return.
CREATE TABLE TestTable2
(
RowNo INT NOT NULL,
ID INT NOT NULL,
MasterOrder HierarchyID NOT NULL,
SeqNo INT NOT NULL
)
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845192, '/', 1);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845196, '/1/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845194, '/1/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845193, '/1/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845238, '/10/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845239, '/10/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845242, '/11/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845241, '/11/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845245, '/12/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845244, '/12/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845243, '/12/', 1); -- No! ...has children.
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845246, '/12/1/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845264, '/12/10/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845263, '/12/10/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845247, '/12/2/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845249, '/12/3/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845251, '/12/4/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845252, '/12/5/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845254, '/12/6/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845257, '/12/7/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845256, '/12/7/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845260, '/12/8/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845261, '/12/8/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845262, '/12/9/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845267, '/13/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845268, '/13/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845266, '/13/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845272, '/14/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845271, '/14/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845269, '/14/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845276, '/15/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845275, '/15/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845273, '/15/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845278, '/16/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845277, '/16/', 1); -- No! ...has children.
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845279, '/16/1/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845296, '/16/10/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845297, '/16/10/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845299, '/16/11/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845301, '/16/12/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845302, '/16/12/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845304, '/16/13/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845309, '/16/14/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845308, '/16/14/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845306, '/16/14/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (3, 845313, '/16/15/', 3);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (2, 845312, '/16/15/', 2);
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845310, '/16/15/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845281, '/16/2/', 1); -- <<<
INSERT INTO TestTable2 (RowNo, ID, MasterOrder, SeqNo) VALUES (1, 845282, '/16/3/', 1); -- <<<
The RowNo
column is originally a ROW_NUMBER
column I added, it gives order number for the same hierarchy items (with identical hierarchy string). It has always one "1" for each leaf, even if the original sequence number starts i.e. with 3 (because 1 and 2 are excluded due to their state).
So the task is to get all the "leafs" with RowNo = 1
.
Any help is appreciated.