Skip to content

Instantly share code, notes, and snippets.

@radium226
Last active August 29, 2015 14:11
Show Gist options
  • Save radium226/9ef3474cf3da2973dd64 to your computer and use it in GitHub Desktop.
Save radium226/9ef3474cf3da2973dd64 to your computer and use it in GitHub Desktop.
This is an example on how to compute a rollup sum over a hierarchy.
CREATE TABLE
t_folders (
id INTEGER,
parent_id INTEGER,
name VARCHAR2(100)
);
CREATE TABLE
t_files (
id INTEGER,
folder_id INTEGER,
name VARCHAR2(100),
weight NUMBER
);
INSERT INTO t_folders(id, parent_id, name) VALUES (0, NULL, 'Folder #0');
INSERT INTO t_folders(id, parent_id, name) VALUES (1, 0, 'Folder #1');
INSERT INTO t_folders(id, parent_id, name) VALUES (2, 0, 'Folder #2');
INSERT INTO t_folders(id, parent_id, name) VALUES (3, 1, 'Folder #3');
INSERT INTO t_folders(id, parent_id, name) VALUES (4, 1, 'Folder #4');
INSERT INTO t_folders(id, parent_id, name) VALUES (5, 2, 'Folder #5');
INSERT INTO t_folders(id, parent_id, name) VALUES (6, 2, 'Folder #6');
COMMIT;
INSERT INTO t_files(id, folder_id, name, weight) VALUES (7, 5, 'File #1', 10);
INSERT INTO t_files(id, folder_id, name, weight) VALUES (8, 2, 'File #2', 13);
COMMIT;
SELECT
SYS_CONNECT_BY_PATH(f.name, '/') path,
CONNECT_BY_ISLEAF has_child
FROM
t_folders f
CONNECT BY
PRIOR f.id = f.parent_id
START WITH
f.parent_id IS NULL;
SELECT
p.path,
h.weight
FROM
(
SELECT
h.id,
h.type,
h.weight
FROM
(
SELECT
f.id,
LEVEL nested_level,
SUM(f.weight) OVER (PARTITION BY CONNECT_BY_ROOT(f.id)) weight,
f.type
FROM
(
(
SELECT
f.id,
f.parent_id,
f.name,
0 weight, -- A folder has no weight
'FOLDER' type -- Used to distinguish folders and file
FROM
t_folders f
) UNION ALL (
SELECT
-1 id, -- We use a fake ID to be consistent
f.folder_id parent_id,
f.name,
f.weight,
'FILE' type
FROM
t_files f
)
) f
CONNECT BY
PRIOR f.id = f.parent_id
) h
WHERE
h.nested_level = 1
AND h.type = 'FOLDER'
) h
JOIN
(
SELECT
f.id,
SYS_CONNECT_BY_PATH(f.name, '/') path
FROM
t_folders f
CONNECT BY
PRIOR f.id = f.parent_id
START WITH
f.parent_id IS NULL
) p
ON
p.id = h.id;
DROP TABLE
t_files;
DROP TABLE
t_folders;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment