Hierarchical Queries
Hi community,
I need to write an SQL query with hierarchical order, I have a table with a column referencing itself, similar as the sample bellow:
ID |
DATE |
MESSAGE |
LOGIN |
PARENT_ID |
1 |
27/01/21 |
Bacon ipsum dolor amet pork shoulder ribs |
User 1 |
|
2 |
27/01/21 |
Gouda croque monsieur emmental. |
User 2 |
1 |
3 |
27/01/21 |
Manchego fromage frais airedale |
User 3 |
2 |
Oracle database has Hierarchical Query, to do something like that:
SELECT id, MESSAGE, parent_id FROM messages CONNECT BY PRIOR id = parent_id;
Is it possible to do something like that in Caché?
Thanks in advance
Product version: Caché 2018.1
$ZV: Cache for UNIX (Oracle Solaris for SPARC-64) 2018.1.3 (Build 414_0_20009) Wed Jun 17 2020 12:17:10 EDT
There's nothing built-in for this, but you can simulate it via custom class queries or %SQL.AbstractFind. I have an implementation of %SQL.AbstractFind/%Library.FunctionalIndex that does some things with hierarchies but falls short of the capabilities you linked in the Oracle doc. Specifically, it can find all ancestors/descendants/both (the whole tree) in a hierarchy efficiently, but it doesn't follow the same rules around ordering and won't let you do paths and such. (I'd want to clean it up a good deal before sharing, but that's probably worthwhile at some point.)
With what we've done the syntax ends up looking like:
Class DC.Demo.Hierarchy Extends %Persistent [ MemberSuper = AppS.Index.Methods ] { Property message As %String; Property login As %String; Property parentId As DC.Demo.Hierarchy [ SqlFieldName = parent_id ]; Index parentId On parentId [ Type = bitmap ]; ClassMethod RunDemo() { Do ..%KillExtent() &sql(insert into DC_Demo.Hierarchy (message, login, parent_id) values ('Bacon ipsum dolor amet pork shoulder ribs', 'User 1', null)) &sql(insert into DC_Demo.Hierarchy (message, login, parent_id) values ('BGouda croque monsieur emmental.', 'User 2', 1)) &sql(insert into DC_Demo.Hierarchy (message, login, parent_id) values ('Manchego fromage frais airedale', 'User 3', 2)) Do ##class(%SQL.Statement).%ExecDirect(, "select id, message, parent_id from DC_Demo.Hierarchy "_ "where id %FIND DC_Demo.Hierarchy_parentIdFind(2,'all descendants')").%Display() Do ##class(%SQL.Statement).%ExecDirect(, "select id, message, parent_id from DC_Demo.Hierarchy "_ "where id %FIND DC_Demo.Hierarchy_parentIdFind(3,'all related')").%Display() } }
Because there's a self-referencing property with a bitmap index, the hierarchy support is automatic via the MemberSuper class. Output is:
Help me a lot, thanks @Timothy Leavitt
Globals look ideal for such cases. Maybe it’s doable with custom queries somehow?